On Sat, Dec 12, 2009 at 7:15 PM, Tom Machinski <tom.machin...@gmail.com> wrote: > In most cases, `list(generator)` works as expected. Thus, > `list(<generator expression>)` is generally equivalent to `[<generator > expression>]`. >
Actually, it's list(generator) vs. a list comprehension. I agree that it can be confusing, but Python considers them to be two different constructs. >>> list(xrange(10)) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> [xrange(10)] [xrange(10)] > Here's a minimal case where this equivalence breaks, causing a serious > and hard-to-detect bug in a program: > > >>> def sit(): raise StopIteration() > ... > >>> [f() for f in (lambda:1, sit, lambda:2)] > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > File "<stdin>", line 1, in sit > StopIteration > >>> list(f() for f in (lambda:1, sit, lambda:2)) > [1] > > I was bitten hard by this inconsistency when sit() was returning the > idiom `(foo for foo in bar if foo.is_baz()).next()`. The nonexistence > of a foo with is_baz() True in that query raises an exception as > designed, which expresses itself when I use the list comprehension > version of the code above; the generator version muffles the error and > silently introduces a subtle, confusing bug: `lambda:2` is never > reached, and a truncated list of 1 element (instead of 3) is > "successfully" generated.. > > Just wondered what you guys think, > > -- Tom > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://mail.python.org/mailman/listinfo/python-list