解压缩一般化

wim*_*wim 28 python list-comprehension python-3.x iterable-unpacking python-3.5

>>> LOL = [[1, 2], ['three']]
>>> [*LOL[0], *LOL[1]]
[1, 2, 'three']
Run Code Online (Sandbox Code Playgroud)

好的!再见itertools.chain.反正从来没有喜欢过你.

>>> [*L for L in LOL]
  File "<ipython-input-21-e86d2c09c33f>", line 1
    [*L for L in LOL]
    ^
SyntaxError: iterable unpacking cannot be used in comprehension
Run Code Online (Sandbox Code Playgroud)

.为什么我们不能拥有美好的东西?

理解中的解包似乎很明显/ pythonic,但由于他们不愿意添加该特殊错误消息,因此有理由禁用它.那么,该语法有什么问题?

Jim*_*ard 19

接受此功能的Py-Dev邮件列表线程中引用:

这就是理解.IIRC,在补丁的开发过程中,我们意识到这f(*x for x in xs)非常模糊的,我们决定不允许它 - 注意这f(x for x in xs)已经是一种特殊情况,因为如果它是唯一的参数,参数只能是"裸"的生成器表达式.同样的推理不适用于(以那种形式)列表,集合和字典理解 - 虽然f(x for x in xs)在含义上是相同的f((x for x in xs)),但是[x for x in xs]不一样[(x for x in xs)](这是一个元素的列表,元素是生成器表达式)

(强调我的)

我还看了一下这个功能的Python问题跟踪器.我发现了一个在实施过程中进行讨论的问题.帮助他们实现这一目标的消息序列从这里开始,对GvR 在msg234766中介绍的歧义进行了很好的概述.

恐惧链接腐的,我在这里的附加(格式化)消息:

所以我认为这里的测试功能应该是:

def f(*a, **k): print(list(a), list(k))
Run Code Online (Sandbox Code Playgroud)

然后我们可以尝试这样的事情:

f(x for x in ['ab', 'cd'])
Run Code Online (Sandbox Code Playgroud)

它打印一个生成器对象,因为它被解释为一个生成器表达式的参数.

但现在让我们考虑一下:

f(*x for x in ['ab', 'cd'])
Run Code Online (Sandbox Code Playgroud)

我个人认为这相当于:

f(*'ab', *'cd')
Run Code Online (Sandbox Code Playgroud)

IOW:

 f('a', 'b', 'c', 'd')
Run Code Online (Sandbox Code Playgroud)

PEP没有说清楚这里要做什么.现在的问题是,我们应该将诸如*x for x in ...扩展形式的生成器表达式之类的东西解释为,还是作为扩展形式的*arg?我不知何故认为后者更有用,也更符合逻辑.

我的理由是PEP支持类似的东西,f(*a, *b)并且解释f(*x for x in xs)*xx列表中的每个人做事情是相当合乎逻辑的xs.

最后,如相应PEP的摘要部分所述,此功能并未完全排除:

这个PEP不包括列表,集合和字典理解中的解包操作符,尽管这未被排除在未来的提议中.

所以,我们可能很快就会看到它(绝对不是3.6,但是:-)而且我希望我们这样做,它们看起来不错.

  • IOW ="换句话说"(不得不谷歌) (8认同)

Del*_*gan 11

PEP 448 简要介绍了这一点,它引入了解包概括:

此PEP的早期迭代允许将列表,集合和字典理解中的运算符解包为可迭代的容器迭代运算符:

>>> ranges = [range(i) for i in range(5)]
>>> [*item for item in ranges]
[0, 0, 1, 0, 1, 2, 0, 1, 2, 3]

>>> {*item for item in ranges}
{0, 1, 2, 3}
Run Code Online (Sandbox Code Playgroud)

这引起了人们对可读性和温和支持的强烈担忧.为了不使PEP中争议较少的方面处于不利地位,该提案的其余部分不接受这一点.

但是,这可能会在未来发生变化:

这个PEP不包括列表,集合和字典理解中的解包操作符,尽管这未被排除在未来的提议中.

  • 这就是我一直在寻找的,谢谢!Steven D'Aprano 的信息很奇怪 - 对 *for 循环 + 扩展 * 的解包概括是明显且自然的。很难理解核心开发人员如何认为它“*非常奇怪*”和“*一百万年都不会*”期望这样的结果。 (2认同)