I am trying to make a class which inherits from a python list. I want the elements of the list to be initialized/finalized with every loop of the list. I thought this could be done by overriding the __iter__
method of the python list but I can't seem to get it to work. The __iter__
method appears to 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
Output
[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?
You can simply return a 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 in place of the generator expression which makes for easier debugging
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 could 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