Recursive list comprehension
steven.bethard at gmail.com
Wed Dec 8 21:42:27 CET 2004
Peter Otten wrote:
> I noted that strings
> don't feature an __iter__ attribute. Therefore obj.__iter__() is not
> equivalent to iter(obj) for strings. Do you (plural) know whether this is a
> CPython implementation accident or can be relied upon?
Nick Craig-Wood wrote:
> With a little more investigation I see that str has no __iter__
> method. However you can call iter() on a str
> ...and this works because str supports __getitem__ according to the
> So there is some magic going on here! Is str defined to never have an
> __iter__ method? I see no reason why that it couldn't one day have an
> __iter__ method though.
The magic is the old-style iteration protocol (also called the 'sequence
protocol') which calls __getitem__ starting at 0 until an IndexError is
raised. From the docs:
iter( o[, sentinel])
Return an iterator object. The first argument is interpreted very
differently depending on the presence of the second argument. Without a
second argument, o must be a collection object which supports the
iteration protocol (the __iter__() method), or it must support the
sequence protocol (the __getitem__() method with integer arguments
starting at 0). If it does not support either of those protocols,
TypeError is raised...
I looked around to see if there was any talk specifically of str and
__iter__/__getitem__ and couldn't find any. (Though I wouldn't claim
that this means it's not out there.) ;) My guess is that there isn't
any guarantee that str objects might not one day grow an __iter__
method, so I wouldn't rely on it.
See my other post that uses iter() and TypeError instead of .__iter__()
and AttributeError -- it's relatively simple to avoid relying on
.__iter__, and doing so also allows you to support other objects that
support the sequence protocol but have no __iter__ method.
More information about the Python-list