Dangerous behavior of list(generator)
Gabriel Genellina
gagsl-py2 at yahoo.com.ar
Sun Dec 13 03:53:33 EST 2009
En Sat, 12 Dec 2009 23:43:20 -0300, Ned Deily <nad at acm.org> escribió:
> In article <nad-8CDB63.18012412122009 at news.gmane.org>,
> Ned Deily <nad at acm.org> wrote:
>> In article
>> <ec96e1390912121653w56c3dbe3p859a7b979026bf47 at mail.gmail.com>,
>> Benjamin Kaplan <benjamin.kaplan at case.edu> wrote:
>> > On Sat, Dec 12, 2009 at 7:15 PM, Tom Machinski
>> <tom.machinski at gmail.com>
>> > wrote:
>> > > >>> 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]
>> > > 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.
I think nobody has addressed the OP arguments (as I understand them).
First, except the obvious outer delimiters (and some corner cases in 2.x,
fixed in Python 3), a list comprehension and a generator expression share
the same syntax: (x for x in some_values) vs [x for x in some_values].
Also, *almost* always, both list(<comprehension>) and [<comprehension>],
when evaluated, yield the same result [1]. *Almost* because StopIteration
is handled differently as the OP discovered: the list comprehension
propagates a StopIteration exception to its caller; the list constructor
swallows the exception and the caller never sees it.
Despite a promise in PEP 289, generator expressions semantics isn't
explained in detail in the language reference. I can't tell if the
difference is intentional, accidental, undocumented behavior, an
implementation accident, a bug, or what...
[1] <comprehension> being a syntactic construct like:
x**2 for x in range(5)
or:
f() for f in [lambda:1, sit, lambda:2]
--
Gabriel Genellina
More information about the Python-list
mailing list