列表理解 - 当结果收集在列表中时循环向后展开

List Comprehension - loop unrolling backwards when results collected inside list

这是我之前得到答案的转贴,但我只是不清楚语法,希望有人解释发生了什么,否则我只会记住这里的 "rule"。

此表达式按预期工作,但将矩阵中的每个字符返回到一个列表中:

[char for line in grid for i,char in enumerate(line) if len(line[i:])>3]

如果我想让矩阵中的每个字符都保留在它对应的列表(或此处的行)中,我希望下面的代码能够工作(以保留循环展开顺序,其中内部循环 [理解中最右边的循环]

[[char for line in grid] for i,char in enumerate(line) if len(line[i:])>3]

这给出了一个 NameError not defined...所以我了解到合适的结构是:

[[char for i,char in enumerate(line) if len(line[i:])>3] for line in grid]

我一直都在使用理解,我想我只是还没有遇到过这个,所以它让我感到惊讶,但似乎在理解中创建列表需要我们从本质上颠倒循环顺序,现在最右边的 for 语句实际上先执行,而不是左边,或者与正常的列表 comp 语法相反。

我在网上和书中找到了几个例子(例如矩阵的每个元素的平方)来确认语法,但它们都掩盖了这样一个事实:当列表用于累加时,for 循环突然颠倒顺序结果在理解中。

考虑到上述情况,for 语句并不总是在理解中执行 left/right 是否公平?

不,这是嵌套列表理解的一个实例,它根本不同

[char for line in grid for i,char in enumerate(line) if len(line[i:])>3]

相当于

 for line in grid:
     for i,char in enumerate(line):
         if len(line[i:]) > 3:
            new_list.append(char)

你的第二个例子

[[char for i,char in enumerate(line) if len(line[i:])>3] for line in grid]

相当于

for line in grid:
    new_list.append([char for i,char in enumerate(line) if len(line[i:])>3])

在任何单个列表推导中,for语句从左到右总是

comprehensions 的语法是 (for Python 3.x) from documentation -

comprehension ::= expression comp_for

comp_for ::= "for" target_list "in" or_test [comp_iter]

comp_iter ::= comp_for | comp_if

comp_if ::= "if" expression_nocond [comp_iter]

其中 expression 可以是任何表达式,例如 - 文字或数学表达式或函数调用或元组或列表,甚至是另一个列表理解。表达式列表 here.

中的任何表达式

for 单个列表理解中的循环总是从左到右执行,正如您从上面的语法中看到的那样。但是我们可以有嵌套的列表理解(即列表理解作为另一个列表理解的表达式,等等)。

当你这样做时 -

[[char for i,char in enumerate(line) if len(line[i:])>3] for line in grid]

有两种列表推导式(因为您正在创建列表列表)一种创建外部列表的推导式和一种创建内部列表的推导式。

所以外部列表理解看起来像 -

[<inner list comprehension> for line in grid]

而内部列表理解是 -

[char for i,char in enumerate(line) if len(line[i:])>3]