问题
Why and how does it works? For example I'm writing a list comprehension like this:
>>> a = (10, 30, 20)
>>> print([q for q in a])
[10, 30, 20]
At now, if I remove the [], this will also work, but:
>>> a = (10, 30, 20)
>>> print(q for q in a)
<generator object <genexpr> at 0x7fe527d1dca8>
Does Python make a generator here? And if I do this without print():
>>> a = (10, 30, 20)
>>> b = q for q in a
File "<input>", line 1
b = q for q in a
^
SyntaxError: invalid syntax
I'm thinking about because (q for q in a) will make a generator, but that's impossible, however I'm not using two pair of () like:
>>> a = (10, 30, 20)
>>> print((q for q in a)) # here is two pair of `()`
<generator object <genexpr> at 0x7fe527d1dca8>
回答1:
Does Python make a generator here?
Yes. Quoting official documentation of Generator expressions,
The parentheses can be omitted on calls with only one argument.
Note that this is the only exception from the actual syntax
generator_expression ::= "(" expression comp_for ")"
So, when you did
b = q for q in a
Python was not able to parse it, as it is not a valid Python expression. That is why you were getting a SyntaxError.
If you actually wanted to print all the elements from the generator expression, you can unpack the result of it to the print function, as suggested by Blckknght, like this
>>> a = (10, 30, 20)
>>> print(*(q for q in a))
10 30 20
回答2:
In Python 3.x, print is a function.
Normally, when you try to create a generator expression and store it in a variable (or in some other places), you need to enclose it in () . Example -
b = (q for q in a)
But if you are passing a generator expression to a function as a psotional argument, and it is the only argument , then you do not need the enclosing () .
It is explained in the PEP 0289 -
if a function call has a single positional argument, it can be a generator expression without extra parentheses, but in all other cases you have to parenthesize it.
Or the documentation (As also given by the other answer) -
The parentheses can be omitted on calls with only one argument.
回答3:
The parentheses aren't what make a generator, just like they aren't what make a tuple. Something like return 2,3 will return the tuple of (2, 3):
>>> def f():
... return 2,3
...
>>> f()
(2, 3)
>>> type(f())
<class 'tuple'>
You can make a tuple with a single character with just the comma:
>>> 2,
(2,)
>>> a = 2,
>>> type(a)
<class 'tuple'>
You only need the parentheses when they provide disambiguation for the syntax, such as [(a,b) for a,b in zip([1,2], [1,2])].
>>> [a,b for a,b in zip([1,2], [1,2])]
File "<stdin>", line 1
[a,b for a,b in zip([1,2], [1,2])]
^
SyntaxError: invalid syntax
>>> [(a,b) for a,b in zip([1,2], [1,2])]
[(1, 1), (2, 2)]
Regarding the print() call, if you include the parentheses you can then use the * operator to unpack the generator:
>>> a = (10, 30, 20)
>>> print([q for q in a])
[10, 30, 20]
>>> print(q for q in a)
<generator object <genexpr> at 0x0000000003B84B88>
>>> print(*(q for q in a))
10 30 20
>>> print(*(q for q in a if q<25))
10 20
>>> print(*a)
10 30 20
This occasionally saves some typing.
来源:https://stackoverflow.com/questions/33051704/use-for-in-print-will-give-a-generator-on-python-3-x