为什么python列表理解控制循环嵌套在当前形式中?

时间:2017-03-02 14:09:12

标签: python list-comprehension

为什么从左到右评估python列表推导?例如,正确的语法是:

[item for sublist in superlist for item in sublist]

但是对我来说似乎更容易得到以下内容:

[item for item in sublist for sublist in superlist]

因为它与以下类似:

[[item for item in sublist] for sublist in superlist]

哪个也是有效的python。

2 个答案:

答案 0 :(得分:3)

首先要看的是PEP 202: List Comprehensions。在PEP中,BDFL(Guido van Rossum)宣称:

  

表单[... for x... for y...]嵌套,最后一个索引变化最快,就像嵌套的for循环一样。

但这并没有告诉我们为什么。 Guido van Rossum在“Python的历史”From List Comprehensions to Generator Expressions中告诉我们

  

在Python 2.0中添加了列表推导。此功能   由Greg Ewing发起的一系列补丁,由Skip Montanaro和Thomas Wouters贡献。 (IIRC蒂姆彼得斯也非常强烈   赞同这个想法。)

Greg Ewing于1999年9月发表Python List Comprehensions Enhancement

  

此增强功能扩展了Python 1.5.2的语法以包含内容   在其他一些语言中称为列表推导。这是   一些例子:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
fruit = ["Apple", "Banana", "Pear"]
mult3 = [3 * x for x in numbers]
evens = [x for x in numbers if x % 2 == 0]
crossprod = [(x, y) for x in numbers for y in fruits]

进一步

  

语义是语句

x = [e for v1 in s1 for v2 in s2 ... if t ...]
     

相当于

x = []
for v1 in s1:
  for v2 in s2:
    ...
      if t:
        ...
          x.append(e)

再次注意,Greg Ewing没有告诉我们为什么 for-loops具有他们所做的顺序。他简单地提出了完全形成的想法。也许线索在于他暗示“在其他一些语言中已知的列表理解”。

我还浏览了在添加列表推导之前的python-dev邮件列表中的整个讨论,我无法深究这一点。有人争论是否应该允许嵌套。有一个有趣的兔子踪迹,关于列表推导中并行处理的建议语法,当他们意识到他们可以发明内置zip时被拒绝。关于循环的顺序没有争论。

无论排序的原因如何,列表推导中for循环的顺序遵循它们在正常for循环中出现的顺序。

result = []
for sublist in superlist:
    for item in superlist:
        result.append(item)

变为

result = [item for sublist in superlist for item in sublist]

另一种观察方式是定期for循环嵌套增加缩进。增加缩进是从左到右的移动。同样地,通过从左到右的结构来完成在理解中的嵌套。

注意: Why is Python's list comprehension loop order backwards? [closed]也解决了这个问题。投票结束这个问题的人之一是“主要以观点为基础”的人是蒂姆·彼得斯,他是Guido van Rossum认为是向Python添加列表理解的冠军之一。所以你不会在这个问题上得到明确的答案。

答案 1 :(得分:2)

根据PEP 202: List Comprehensions(参见"基本原理"),BDFL已下令:

  

表单[... for x... for y...]嵌套,最后一个索引变化最快,就像嵌套的for循环一样。