这是我从早些时候获得答案的转贴,但我不清楚语法,并希望有人解释发生了什么,我只会记住"规则"这里。
此表达式按预期工作,但将矩阵中的每个字符放回一个列表中:
[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]
我一直在使用理解,我想我还没有遇到过这种情况,所以它让我感到惊讶,但似乎在理解中创建列表需要我们基本上颠倒循环顺序现在最右边的语句实际上先执行,而不是左,或从正常列表comp语法中反转。
我在网上和书中发现了几个例子(例如,对矩阵的每个元素进行平方),这些例子确认了语法,但它们都掩盖了当列表用于累积时for循环突然颠倒顺序的事实理解中的结果。
对于陈述并不总是在理解中左/右执行是否公平的陈述,如上所述?
答案 0 :(得分:3)
这不是嵌套列表理解的实例,它是根本不同的
[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语句从左到右始终。
答案 1 :(得分:1)
理解的语法是(对于Python 3.x)来自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]