Boolean value of generators

Cameron Simpson cs at
Thu Oct 14 14:48:54 CEST 2010

On 14Oct2010 10:16, Tony <tony10 at> wrote:
| I have been using generators for the first time and wanted to check for
| an empty result.  Naively I assumed that generators would give
| appopriate boolean values.  For example
| def xx():
|   l = []
|   for x in l:
|     yield x
| y = xx()
| bool(y)
| I expected the last line to return False but it actually returns True.
| Is there anyway I can enhance my generator or iterator to have the
| desired effect?

The generator is not the same as the values it yields.
What you're doing is like this:

  >>> def f():
  ...   return False
  >>> bool(f)
  >>> bool(f())

In your code, xx() returns a generator object. It is not None, nor any
kind of "false"-ish value. So bool() returns True.

The generator hasn't even _run_ at that point, so nobody has any idea if
iterating over it will return an empty sequence.

What you want is something like this:

  values = list(xx())

or more clearly:

  gen = xx()
  values = list(gen)

You can see here that you actually have to iterate over the generator
before you know if it is (will be) empty.

Try this program:

  def lines():
    print "opening foo"
    for line in open("foo"):
      yield line
    print "closing foo"

  print "get generator"
  L = lines()
  print "iterate"
  text = list(L)
  print "done"

For me it does this:

  get generator
  opening foo
  closing foo

You can see there that the generator _body_ doesn't even run until you
start the iteration.

Does this clarify things for you?

Cameron Simpson <cs at> DoD#743

Winter is gods' way of telling us to polish.
        - Peter Harper <bo165 at> <harperp at>

More information about the Python-list mailing list