Recursive list comprehension

Steven Bethard steven.bethard at
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
 > docs.
 > 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 mailing list