Python list __iter__ method invoked in each loop?

I am trying to create a class that inherits from a python list. I want the list items to be initialized / finalized with each list loop. I thought this could be done by overriding the __iter__ method in the python list, but I can't get it to work. __iter__ method called only once? (see below)

 class MyList(list): def __iter__(self): print 'do something' return list.__iter__(self) my_list = MyList(range(10)) print my_list for item in my_list: print item 

Exit

 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] do something 0 1 2 3 4 5 6 7 8 9 

Any idea how I can achieve what I want to do?

+6
python iterator loops
source share
5 answers

You can simply return the generator expression from __iter__()

 class MyList(list): def __iter__(self): return (self.do_something(x) for x in list.__iter__(self)) def do_something(self, x): print 'do something', x return x my_list = MyList(range(10)) print my_list for item in my_list: print item 

ncoghlan suggests using a generator instead of a generator expression, making debugging easier

 class MyList(list): def __iter__(self): for x in list.__iter__(self): yield self.do_something(x) def do_something(self, x): print 'do something', x return x my_list = MyList(range(10)) print my_list for item in my_list: print item 

Alternatively you can use imap here

 from itertools import imap class MyList(list): def __iter__(self): return imap(self.do_something, list.__iter__(self)) def do_something(self, x): print 'do something', x return x my_list = MyList(range(10)) print my_list for item in my_list: print item 
+7
source share

__iter__ returns an iterator object. If you need to do something at each iteration, you must implement your own (it must implement the two methods described in the related documents).

+3
source share

The python class method __iter__() actually returns an iterator object. For reference, see the following: http://docs.python.org/library/stdtypes.html#iterator-types

In the iterative object, at each step of the loop, the next() method will be called. You can write your own iterator, which will be returned by your custom list.

+2
source share

I want list items to be initialized / finalized with each list loop

The list does not have direct control over this. Several loops can access the list in parallel (for example, in nested loops). Each loop is controlled by an iterator, and __iter__() should return iterators on every call. You cannot return the same instance of an iterator all the time, because the specified parallel loops will interfere with each other.

But inside the iterator, you can create the elements you need. Completing them inside an iterator is hardly reasonable, because as soon as you return the element, you have lost control over it. If you complete it at a later time, external code that still relies on the element may fail. If you need to refine your products, blame them on the consumer of the goods.

0
source share

I do not understand exactly what you are trying to do, but what you have already said is true. next() is a method that is called at each iteration.

 class MyList(list): def next(self): print "Do something" return list.next(self) 

(I did not test it)

-2
source share

All Articles