为什么从左到右评估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。
答案 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
循环一样。