Can I create a "view" on a Python list? Can I create a "view" on a Python list? arrays arrays

Can I create a "view" on a Python list?


There is no "list slice" class in the Python standard library (nor is one built-in). So, you do need a class, though it need not be big -- especially if you're content with a "readonly" and "compact" slice. E.g.:

import collectionsclass ROListSlice(collections.Sequence):    def __init__(self, alist, start, alen):        self.alist = alist        self.start = start        self.alen = alen    def __len__(self):        return self.alen    def adj(self, i):        if i<0: i += self.alen        return i + self.start    def __getitem__(self, i):        return self.alist[self.adj(i)]

This has some limitations (doesn't support "slicing a slice") but for most purposes might be OK.

To make this sequence r/w you need to add __setitem__, __delitem__, and insert:

class ListSlice(ROListSlice):    def __setitem__(self, i, v):        self.alist[self.adj(i)] = v    def __delitem__(self, i, v):        del self.alist[self.adj(i)]        self.alen -= 1    def insert(self, i, v):        self.alist.insert(self.adj(i), v)        self.alen += 1


Perhaps just use a numpy array:

In [19]: import numpy as npIn [20]: l=np.arange(10)

Basic slicing numpy arrays returns a view, not a copy:

In [21]: lv=l[3:6]In [22]: lvOut[22]: array([3, 4, 5])

Altering l affects lv:

In [23]: l[4]=-1In [24]: lvOut[24]: array([ 3, -1,  5])

And altering lv affects l:

In [25]: lv[1]=4In [26]: lOut[26]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])


You can do that by creating your own generator using the original list reference.

l = [1,2,3,4,5]lv = (l[i] for i in range(1,4))lv.next()   # 2l[2]=-1lv.next()   # -1lv.next()   # 4

However this being a generator, you can only go through the list once, forwards and it will explode if you remove more elements than you requested with range.