Python List理解执行顺序 [英] Python List comprehension execution order

查看:61
本文介绍了Python List理解执行顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
squared = [[x**2 for x in row] for row in matrix]
print(squared)

在前面的数据结构和列表理解中,执行的顺序是什么?

In the preceding data structure and list comprehension, what is the order of execution?

从视觉上看,它似乎是从右到左处理.考虑到嵌套列表首先必须是可访问的,然后才能对它的每个单独的项进行平方.

Visually it appears to process from right to left. Considering the nested list first has to be access before each of its individual items can be squared.

推荐答案

元素顺序

PEP 202 并不十分全面,但是您可以在 Python中找到一些信息语言参考:

Order of elements

The PEP 202 is not very... comprehensive, but you can found some information in the Python Language Reference:

该理解包括一个表达式,后跟至少一个for子句和零个或多个for或if子句.在这种情况下,新容器的元素是通过将每个for或if子句视为一个块,从左到右嵌套,并在每次到达最内层的块时评估表达式以产生一个元素而生成的元素.[...]最左边的for子句中的可迭代表达式在封闭范围内直接求值,然后作为参数传递给隐式嵌套范围.

The comprehension consists of a single expression followed by at least one for clause and zero or more for or if clauses. In this case, the elements of the new container are those that would be produced by considering each of the for or if clauses a block, nesting from left to right, and evaluating the expression to produce an element each time the innermost block is reached. [...] The iterable expression in the leftmost for clause is evaluated directly in the enclosing scope and then passed as an argument to the implictly nested scope.

因此,列表理解是从左向右进行 个块.

Therefore list comprehension proceeds for blocks from left to right.

但是,在您的情况下,您有两个列表理解,每个列表理解都一个区块:

But in your case, you have two list comprehensions having each one block:

  • 外部列表理解:为 matrix 中的每个 row 做某事;
  • 内部列表理解(用 row 做一些事情):对 row 中的每个 x 做其他事情.
  • outer list comprehension: do something for each row in matrix;
  • inner list comprehension(do something with row): do something else for each x in row.

这就是为什么你的列表理解最好从右到左阅读.使用函数更容易看到:

That's why your list comprehension is better read from right to left. It is easier to see with a function:

>>> def square_elements(row): return [x**2 for x in row] # inner
...
>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> [square_elements(row) for row in matrix] # outer
[[1, 4, 9], [16, 25, 36], [49, 64, 81]]

现在考虑一个两个阻止列表的理解:

Consider now a two blocks list comprehension:

>>> [x**2 for row in matrix for x in row]
[1, 4, 9, 16, 25, 36, 49, 64, 81]

您会看到从左到右的顺序.在第一种情况下,您具有: matrix 中的每个 row 做某事,并且要做的是:为每个 x 在 row 中.在第二种情况下,它是: matrix 中的每个 row 中的每个 x 做某事.

You see the left to right order. In the first case, you have: do something for each row in matrix, and that something is: do something else for each x in row. In the second case it is: do something for each x of each row in matrix.

这是您提出的问题,即使我不确定这是您想提出的问题!该操作以什么顺序执行?规范似乎没有对这个问题说什么,但答案是:没关系,只要您避免列表理解中的副作用即可.如果您从列表理解中获得列表(不引发异常),则无论列表如何构建,都可以保证该列表是完整的.

That's the question you asked, even if I'm not sure that's the question you wanted to ask! In which order the operation are performed? The spec doesn't seem to say anything on this question but the answer is: it doesn't matter, as long as you avoid side effects in your list comprehensions. If you get a list out of a list comprehension (no exception raised), this list is guaranteed to complete, no matter how it was built.

但是,如果您不遵循无副作用"规则,则执行副作用的顺序可能会更改最终结果.您可以使用一种技巧对其进行测试: print 函数返回 None ,因此,如果未打印(...),则始终为正确:

But if you don't follow the "no side-effect" rule, the order in which side effects are performed may change the final result. You can use a trick to test it: the print function returns None, hence if not print(...) is always True:

>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
>>> squared = [[x**2 for x in row if not print("value", x)] for row in matrix if not print("row", row)]
row [1, 2, 3]
value 1
value 2
value 3
row [4, 5, 6]
value 4
value 5
value 6
row [7, 8, 9]
value 7
value 8
value 9
>>> squared
[[1, 4, 9], [16, 25, 36], [49, 64, 81]]

顺序似乎是自然的",但我不认为您应该依赖它(更重要的是:列表理解中不应该有副作用).

The order seems "natural", but I don't think you should rely on it (more important: you should not have side effects in your list comprehensions).

这篇关于Python List理解执行顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆