Skip to content Skip to sidebar Skip to footer

Python List Comprehension Execution Order

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 ord

Solution 1:

Order of elements

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

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:

  • 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:

>>>defsquare_elements(row): return [x**2for 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]

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.

Execution order

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.

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**2for x in row ifnotprint("value", x)] for row in matrix ifnotprint("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).

Solution 2:

The order is from left to right. That is all row elements of the first row will be squared first.

Solution 3:

in list comprehension in Python execute:

for item in lista:
    item * 2

equal:

[item * 2 for item in lista]

Post a Comment for "Python List Comprehension Execution Order"