Dangerous behavior of list(generator)

Martin v. Loewis martin at v.loewis.de
Sat Jan 2 15:17:59 EST 2010


>> Bottom line, I'm going to have to remove this pattern from my code:
>>
>>   foo = (foo for foo in foos if foo.bar).next()

I recommend to rewrite this like so:

def first(gen):
  try:
    return gen.next()
  except StopIteration:
    raise ValueError, "No first value"

foo = first(foo for foo in foos if foo.bar)

As others have said: don't let StopIteration appear unexpectedly;
IOW, consume generators right away in a loop construct (where
this first function is a loop construct as well). A different
way of writing it would be

def first(gen):
  for value in gen:
    return value
  raise ValueError, "empty collection"

Regards,
Martin



More information about the Python-list mailing list