Eli Rose Eli Rose - 2 months ago 4
Python Question

Python comprehensions in function calls (PEP 448)

(This is all on Python 3.5.2)

At the bottom of PEP 448, I see:

Unbracketed comprehensions in function calls, such as
f(x for x in it)
, are already valid.

This is intriguing. If I define the following function:

def f(a, b, c):
return a + b + c

then that wording makes me think that
f(thing for thing in [1, 2, 3]) == 6
. But actually, I get:

>>> f(thing for thing in [1, 2, 3])
TypeError: f() missing 2 required positional arguments: 'b' and 'c'

i.e. the whole generator expression passed as

So what does this sentence in PEP 448 mean? Just that you can pass a generator expression as an argument?


Python allows you to pass a single generator expression to a function you're calling without needing extra parentheses. For instance:

foo(x for x in range(10))

is mostly equivalent to:

genexp = (x for x in range(10)) # parentheses are necessary here

You do still need the parentheses when defining the generator expression if there are other arguments that you're passing to the function call (e.g. foo(w, (x for x in range(10)), y, z), where the second argument is a generator expression of x's).

The PEP was mentioning in passing that a further extension of the unpacking syntax might be confusing in that context. If a new kind of generator expression (*x for x in nested) was legal (it is not part the final PEP, but was being considered for a while), how should foo(*x for x in nested) work? Would it be equivalent to foo((*x for x in nested)) (calling with a single generator expression, that included the new "flattening" *), or would it mean foo(*(x for x in nested)) (which is legal now)?