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
这就是理解.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中介绍的歧义进行了很好的概述.
在恐惧链接腐的,我在这里的附加(格式化)消息:
所以我认为这里的测试功能应该是:
Run Code Online (Sandbox Code Playgroud)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')IOW:
Run Code Online (Sandbox Code Playgroud)f('a', 'b', 'c', 'd')PEP没有说清楚这里要做什么.现在的问题是,我们应该将诸如
*x for x in ...扩展形式的生成器表达式之类的东西解释为,还是作为扩展形式的*arg?我不知何故认为后者更有用,也更符合逻辑.我的理由是PEP支持类似的东西,
f(*a, *b)并且解释f(*x for x in xs)为*x为x列表中的每个人做事情是相当合乎逻辑的xs.
最后,如相应PEP的摘要部分所述,此功能并未完全排除:
这个PEP不包括列表,集合和字典理解中的解包操作符,尽管这未被排除在未来的提议中.
所以,我们可能很快就会看到它(绝对不是3.6,但是:-)而且我希望我们这样做,它们看起来不错.
Del*_*gan 11
PEP 448 简要介绍了这一点,它引入了解包概括:
此PEP的早期迭代允许将列表,集合和字典理解中的运算符解包为可迭代的容器迭代运算符:
Run Code Online (Sandbox Code Playgroud)>>> 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}这引起了人们对可读性和温和支持的强烈担忧.为了不使PEP中争议较少的方面处于不利地位,该提案的其余部分不接受这一点.
但是,这可能会在未来发生变化:
这个PEP不包括列表,集合和字典理解中的解包操作符,尽管这未被排除在未来的提议中.