what should __iter__ return?
Thomas Jollans
thomas at jollybox.de
Fri Sep 3 15:58:38 EDT 2010
On Friday 03 September 2010, it occurred to ernest to exclaim:
> Hi,
>
> What is better:
>
> def __iter__(self):
> for i in len(self):
> yield self[i]
>
> or
>
> def __iter__(self):
> return iter([self[i] for i in range(len(self))])
>
> The first one, I would say is more correct,
> however what if in a middle of an iteration
> the object changes in length? Then, the
> iterator will fail with IndexError (if items
> have been removed), or it will fail to iterate
> over the whole sequence (if items have
> been added).
>
> What do you think?
Hmm. Modifying an object while iterating over it isn't a great idea, ever:
>>> L = [1,2,3,4]
>>> i = iter(L)
>>> next(i)
1
>>> next(i)
2
>>> del L[0]
>>> next(i)
4
You second version is wasteful. It creates a copy of the object just for
iteration. I don't think that's something you should be doing. If you want
"correct" behaviour as with lists, you might want something like this:
def __iter__(self):
class _Iter:
def __init__(it):
it.i = -1
def __next__(it):
it.i += 1
try:
return self[it.i]
except IndexError:
raise StopIteration
return _Iter()
>
> Cheers.
> Ernest
More information about the Python-list
mailing list