[英]List Comprehension - loop unrolling backwards when results collected inside list
这是我早些时候得到答案的一个转贴,但是我只是在语法上不清楚,并且希望有人解释发生了什么,我只是在这里记住“规则”。
该表达式按预期工作,但是将矩阵中的每个字符都归还到一个列表中:
[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 ...,因此我了解到适当的结构是:
[[char for i,char in enumerate(line) if len(line[i:])>3] for line in grid]
我一直都在使用理解,我想我还没有遇到过,所以它让我感到惊讶,但是似乎在理解内创建列表要求我们从本质上颠倒循环顺序,而现在最右边的语句实际上已经执行了首先,而不是左边,或者与常规list comp语法相反。
我在网上和书籍中都找到了一些示例,它们证实了语法,例如,对矩阵的每个元素进行平方运算,但是它们全都掩盖了以下事实:当使用列表在理解内累积结果时,for循环突然颠倒顺序。
鉴于上述情况,对于for语句并非总是以理解的方式左/右执行,这是一个公平的说法吗?
不,这是嵌套列表理解的一个实例,它根本不同
[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语句始终从左到右。
理解的语法来自于文档 (对于Python 3.x)-
理解:: =表达式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
可以是任何表达式,例如-文字或数学表达式或函数调用或元组或列表,甚至另一个列表理解。 这里的表达式列表中的任何表达式。
从上面的语法也可以看出,单个列表推导中的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]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.