bool evaluations of generators vs lists

Albert Hopkins marduk at
Tue Feb 10 14:39:30 EST 2009

On Tue, 2009-02-10 at 11:15 -0800, Josh Dukes wrote:
> quite simply...what???
> In [108]: bool([ x for x in range(10) if False ])
> Out[108]: False
> In [109]: bool( x for x in range(10) if False )
> Out[109]: True
> Why do these two evaluate differently? I was expecting that they would
> evaluate the same but the generator would return true *as soon as the
> first value is detected*. I'd really expect it to act more like...

The first example is a list.  A list of length 0 evaluates to False.

The second example returns a generator object.  A generator object
apparently evaluates to true.  Your example is not iterating of their
values of the generator, but evaluating bool(generator_object) itself.
My feeling is that bool(generator_object) is ambiguous so shouldn't be
used to begin with.

In both examples, bool() doesn't actually iterate over the arguments.
Maybe that's what confused you.

Instead look at this:

>>> type([x for x in range(10) if False ])
<type 'list'>
>>> type((x for x in range(10) if False ))
<type 'generator'>

> def has_values(g):
>      for i in g:
>          return True
>      return False
> So what's going on here? Am I using the wrong function or is this
> actually just a bug?

bool != has_values.  Check for how Python determines the
"truthiness" of an object. Generally speaking the following evaluate to

      * None 
      * False 
      * zero of any numeric type, for example, 0, 0L, 0.0, 0j. 
      * any empty sequence, for example, '', (), []. 
      * any empty mapping, for example, {}. 
      * instances of user-defined classes, if the class defines a
        __nonzero__() or __len__() method, when that method returns the
        integer zero or bool value False.

All other values are considered true -- so objects of many types are
always true.

More information about the Python-list mailing list