在Python中使用生成器表达式和str.join函数

8
当我读到这个问题Python string.join(list) on object array rather than string array时,我发现以下句子:
', '.join(str(x) for x in list)

我已经了解(str(x) for x in list)是一个生成器表达式,我也知道生成器是可迭代的。以下代码验证了我的观点的正确性。

>>> gen = (x for x in [1,2,3])
<generator object <genexpr> at 0x104349b40>
>>> from collections import Iterable
>>> isinstance(gen, Iterable)
True

同时,str.join(iterable)会返回一个字符串,该字符串是可迭代对象中字符串的连接。因此,以下代码可以正常运行。

>>> ",".join((str(x) for x in [1,2,3]))
'123'

那么问题来了,为什么下面的代码也能正常工作,为什么在函数调用时不需要括号。
', '.join(str(x) for x in [1,2,3])

毕竟,str(x) for x in [1,2,3]本身并不是生成器。
>>> tmp = str(x) for x in [1,2,3]
  File "<stdin>", line 1
    tmp = str(x) for x in [1,2,3]
                   ^
SyntaxError: invalid syntax
3个回答

15

这是在引入生成器表达式时指定的(PEP 289):

如果函数调用具有单个位置参数,则可以使用生成器表达式而不需要额外的括号,但在所有其他情况下都必须加上括号。

在您的情况下,它是一个单一位置参数,因此两种方式都可行:

', '.join(str(x) for x in [1,2,3])
', '.join((str(x) for x in [1,2,3]))

2
仔细阅读每个单词后,我发现文档中提到了生成器表达式

拥有一个参数的函数调用时可以省略括号。详见“调用”章节。


2
无论如何,这都是一个生成器表达式 - 但是是否需要使用括号取决于生成器表达式出现的上下文环境。参数列表是一种特殊情况:如果生成器表达式是唯一的参数,则不需要使用括号(但是如果您喜欢,仍然可以使用)。但是,如果调用有多个参数,则需要使用括号。这基本上是引入此功能的PEP中的2B点。请注意保留HTML标签。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接