为什么多个`for`列表理解的顺序是这样的?

问题描述 投票:0回答:3

我知道在嵌套列表理解中拥有多个

for
的正确方法如下(Python 3):

lista = [[[1,2],[3],[4,5,6]],[[7],[8,9]]]

flatlista = [i for k in lista for j in k for i in j]
# results with [1, 2, 3, 4, 5, 6, 7, 8, 9]

但我的自然语言本能强烈反对。我(错误地)期望代码是:

flatlista = [i for i in j for j in k for k in lista]

错误的版本听起来几乎像英语,并且从左到右以一个流的方式阅读。正确的版本需要一些嵌套的阅读技巧,左右跳跃才能涵盖含义。

为什么是这个语法?为什么语言要这样构建?

python python-3.x syntax
3个回答
11
投票

因为这就是 PEP 202 -- 列表推导式 设置的。然而,PEP 并没有完全解释为什么,因为它是事后才创建的;在 PEP 创建之前,甚至在 PEP 流程创建之前,讨论就已经在开发清单上进行了。

首先,该顺序反映了您在 Python 代码中嵌套

for
循环和
if
语句的顺序:

for k in lista:
    for j in k:
        for i in j:

如果您已经习惯了that订购,这会变得非常自然。

看看关于该功能的第一次讨论,其他语言中似乎有排序的先例。事实上,Haskell 具有相同的顺序每个连续的生成器都会细化前一个生成器的结果

当然,在某个时候 Tim Peters(提案发起人)表示今天使用的顺序对他来说是显而易见的,请参阅这篇文章

我已经多次发布了我对今天的 Python 的建议翻译, 其目的是从字面上理解,而不是暗示性的。这个巢穴 “for”与最左边最外面的循环,所以钉住了关于 对所有级别的语义进行排序。为什么这成为了一个争论点 水平超出了我的水平。


2
投票
只要记住卡萨布兰卡的著名台词:“世界上所有城镇的所有杜松子酒酒吧......”然后记住 Python 的等价物是从这句话开始的

backwards

[ginjoint for town in world for ginjoint in town]
因为谁希望他们的编程语言听起来像有史以来最伟大的电影?


0
投票
刚刚找到你的帖子,因为我也想知道同样的事情

嗯,是的 - 似乎应该将其读作扁平的 for 循环

paragraph = ["hi stackoverflow devs!", "i know there is a comment", "that comment is not the same"] letters = [] for sentence in paragraph: for word in sentence.split(" "): if word != "comment": for letter in word: letters.append(letter) letters = [letter for sentence in paragraph for word in sentence.split(" ") if word != "comment" for letter in word] print(letters)
    
© www.soinside.com 2019 - 2024. All rights reserved.