列表理解 - 当结果收集在列表中时循环向后展开
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]
这是我之前得到答案的转贴,但我只是不清楚语法,希望有人解释发生了什么,否则我只会记住这里的 "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]