解压缩一般化

时间:2016-12-20 21:44:27

标签: python python-3.x list-comprehension python-3.5 iterable-unpacking

>>> LOL = [[1, 2], ['three']]
>>> [*LOL[0], *LOL[1]]
[1, 2, 'three']

好的!再见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

即可。为什么我们不能拥有美好的东西?

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

2 个答案:

答案 0 :(得分:18)

引用the Py-Dev mailing list thread in which this feature was accepted

  

这样就可以理解了。 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]与{{}不同1}}(这是一个元素的列表,元素是一个生成器   表达)

(强调我的)

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

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

  

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

[(x for x in xs)]
     

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

def f(*a, **k): print(list(a), list(k))
     

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

     

但现在让我们考虑一下:

f(x for x in ['ab', 'cd'])
     

我个人认为这相当于:

f(*x for x in ['ab', 'cd'])
     

IOW:

f(*'ab', *'cd')
     

PEP没有说清楚这里要做什么。现在的问题是,我们应该将 f('a', 'b', 'c', 'd') 这样的东西解释为生成器表达式的扩展形式,还是*x for x in ...的扩展形式?我不知何故认为后者更有用,也更符合逻辑。

     

我的理由是PEP支持*arg之类的内容,将f(*a, *b)解释为为列表中的每个f(*x for x in xs)执行*x事情是合理的。 {1}}。

最后,如the Abstract section of the corresponding PEP所述,此功能并未完全排除:

  

此PEP不包括列表,集合和字典理解中的解包运算符,尽管未排除未来的提案

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

答案 1 :(得分:11)

这是PEP 448中的简要解释,它引入了解包概括:

  

此PEP的早期迭代允许在内部解包运算符   列表,集合和字典理解作为展平运算符   容器的迭代:

 Private Sub Copy_Formula(Dest As Integer, iCustomer As Long)
  Sheets("INPUT").Cells(2, Dest).Copy Sheets("INPUT").Range(Cells(4, Dest), Cells(3 + iCustomer, Dest))
  Application.CutCopyMode = False
  Calculate

  Sheets("INPUT").Range(Cells(4, Dest), Cells(3 + iCustomer, Dest)).Copy

  Sheets("INPUT").Range(Cells(4, Dest), Cells(3 + iCustomer, Dest)).Cells(1, 1).PasteSpecial _
                            Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks:=False, Transpose:=False
  Application.CutCopyMode = False
 End Sub
     

这引起了人们对可读性和温和性的强烈担忧   支持。为了不利于争议较少的方面   PEP的其余部分不接受这一点。

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

  

此PEP不包括列表,集合和字典理解中的解包运算符,尽管未来的提案未被排除。