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