Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a large list l. I want to create a view from element 4 to 6. I can do it with sequence slice.

>>> l = range(10) >>> lv = l[3:6] >>> lv [3, 4, 5] 

However lv is a copy of a slice of l. If I change the underlying list, lv does not reflect the change.

>>> l[4] = -1 >>> lv [3, 4, 5] 

Vice versa I want modification on lv reflect in l as well. Other than that the list size are not going to be changed.

I'm not looking forward to build a big class to do this. I'm just hoping other Python gurus may know some hidden language trick. Ideally I hope it can be like pointer arithmetic in C:

int lv[] = l + 3; 
like image 598
Wai Yip Tung Avatar asked Aug 14 '10 23:08

Wai Yip Tung


People also ask

How do I view a list in Python?

To find an element in the list, use the Python list index() method, The index() is an inbuilt Python method that searches for an item in the list and returns its index. The index() method finds the given element in the list and returns its position.

How do you add an instance to a list in Python?

We can create list of object in Python by appending class instances to list. By this, every index in the list can point to instance attributes and methods of the class and can access them. If you observe it closely, a list of objects behaves like an array of structures in C.

How do you slice a list in Python?

The format for list slicing is [start:stop:step]. start is the index of the list where slicing starts. stop is the index of the list where slicing ends. step allows you to select nth item within the range start to stop.


1 Answers

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 collections  class 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 
like image 117
Alex Martelli Avatar answered Sep 27 '22 22:09

Alex Martelli