在 `print()` 中使用 `for` 会在 Python 3.x 上生成生成器?

Use `for` in `print()` will give a generator on Python 3.x?

为什么以及如何运作?例如,我正在写一个这样的列表理解:

>>> a = (10, 30, 20)
>>> print([q for q in a])
[10, 30, 20]

现在,如果我删除 [],这也可以,但是:

>>> a = (10, 30, 20)
>>> print(q for q in a)
<generator object <genexpr> at 0x7fe527d1dca8>

这里Python做发电机吗?如果我在没有 print():

的情况下这样做
>>> a = (10, 30, 20)
>>> b = q for q in a

File "<input>", line 1
  b = q for q in a
          ^
SyntaxError: invalid syntax

我正在考虑,因为 (q for q in a) 会制造一个发电机,但那是不可能的,但是我没有使用两对 (),例如:

>>> a = (10, 30, 20)
>>> print((q for q in a)) # here is two pair of `()`
<generator object <genexpr> at 0x7fe527d1dca8>

Does Python make a generator here?

是的。引用Generator expressions

的官方文档

The parentheses can be omitted on calls with only one argument.


请注意,这是实际语法中的唯一例外

generator_expression ::=  "(" expression comp_for ")"

所以,当你这样做时

b = q for q in a

Python 无法解析它,因为它不是有效的 Python 表达式。这就是为什么你得到 SyntaxError.


如果你真的想打印生成器表达式中的所有元素,你可以将它的结果解压到 print 函数,正如 Blckknght 所建议的那样

>>> a = (10, 30, 20)
>>> print(*(q for q in a))
10 30 20

在Python3.x中,print是一个函数。

通常,当您尝试创建生成器表达式并将其存储在变量(或其他一些地方)时,您需要将其包含在 () 中。示例 -

b = (q for q in a)

但是,如果您将生成器表达式作为参数传递给函数,并且它是唯一的参数,那么您不需要封闭的 () .

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.

the documentation(其他答案也给出)-

The parentheses can be omitted on calls with only one argument.

括号不是生成器的组成部分,就像它们不是 tuple 的组成部分一样。 return 2,3 之类的东西会 return tuple of (2, 3):

>>> def f():
...     return 2,3
...
>>> f()
(2, 3)
>>> type(f())
<class 'tuple'>

您可以用单个字符和逗号组成 tuple

>>> 2,
(2,)
>>> a = 2,
>>> type(a)
<class 'tuple'>

您只需要括号来消除语法歧义,例如 [(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)]

关于 print() 调用,如果包含括号,则可以使用 * 运算符解压生成器:

>>> 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

这偶尔会节省一些输入。