__nonzero__ of iterators

Raymond Hettinger python at rcn.com
Mon Apr 5 02:16:24 EDT 2004


[Christian Eder]
> > I just discovered the following pitfall in Python 2.3.
> > Consider the following code :
> >
> >  >>> a = {}
> >  >>> bool (a.keys ())
>  False
> >  >>> bool (a.iterkeys ())
> > True
> >
> > So, an "empty" iterator evaluates to True in boolean context.
> > At a first glance, this is not what one would expect. This causes
> > several problems, e.g. if you operate on something expected to be
> > sequence, and you guard your code with "if seq :" to avoid crashing into
> > an empty sequence, you still crash if you get an empty iterator, even if
> > the rest of your code is able to deal with an iterator as well as with
> > any other sequence type.

This was fixed in Py2.4:

Python 2.4a0 (#46, Apr  4 2004, 05:21:08) [MSC v.1200 32 bit (Intel)]
on win32
IDLE 1.1a0      
>>> d = dict(a=1, b=2, c=3)
>>> it = d.iterkeys()
>>> bool(it)
True
>>> list(it)
['a', 'c', 'b']
>>> bool(it)
False



[John Roth]
> One of the issues is that the iterator many not be able, even in
> principle, be able to figure out whether there is, in fact, a next
> element. Consider a pipe or an internet connection.
> 
> However, you're talking about the special iterator that the
> dictionary object returns. I'm not sure whether this behavior
> is a bug or a feature. It would clearly be possible for that
> iterator object to proxy the __nonzero__ call to the basic
> dictionary object, and from what you show, it doesn't do so.
> 
> I belive this is a quite different issue from a "has next" type
> of function.

Right.  So, the only iterators that provide knowledge of their length
are the ones like dictionaries that know what lies ahead.  For the
rest, the behavior is unchanged (i.e. they do not provide a __len__()
method).


Raymond Hettinger



More information about the Python-list mailing list