Python List comprehension execution order [duplicate]

2024/10/7 14:26:11
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.

Answer

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:

>>> 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]

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**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).

https://en.xdnf.cn/q/118808.html

Related Q&A

Subtract two strings in python

I should calculate the difference between elements two different list. This is my code :import operator a = [5, 35.1, FFD] b = [8.5, 11.3, AMM] difference = [each[0] - each[1] for each in zi…

Python assignment for a phonebook

This weeks lab is based on the example on pages 53,54 of the wikibook "Non-Programmers Tutorial For Python" by Josh Cogliati (2005), (see http://en.wikibooks.org/wiki/Non-Programmer%27s_Tutor…

ImportError: No module named application [duplicate]

This question already has answers here:What is __init__.py for?(14 answers)Closed 6 years ago.I am running a flask application and connecting to database with Flask-mysqlAlchemy when I am running my s…

Detect keypress without drawing canvas or frame on tkinter [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.Want to improve this question? Update the question so it focuses on one problem only by editing this post.Closed 6…

regex to extract a set number of words around a matched word

I was looking around for a way to grab words around a found match, but they were much too complicated for my case. All I need is a regex statement to grab, lets say 10, words before and after a matched…

How do I make a minimal and reproducible example for neural networks?

I would like to know how to make a minimal and reproducible deep learning example for Stack Overflow. I want to make sure that people have enough information to pinpoint the exact problem with my code.…

Increase the capture and stream speed of a video using OpenCV and Python [duplicate]

This question already has answers here:OpenCV real time streaming video capture is slow. How to drop frames or get synced with real time?(4 answers)Closed 2 years ago.I need to take a video and analyz…

Getting Pyphons Tkinter to update a label with a changing variable [duplicate]

This question already has answers here:Making python/tkinter label widget update?(5 answers)Closed 8 years ago.I have a python script which I have written for a Raspberry Pi project, the script reads …

Can someone help me installing pyHook?

I have python 3.5 and I cant install pyHook. I tried every method possible. pip, open the cmd directly from the folder, downloaded almost all the pyHook versions. Still cant install it.I get this error…

What is the bit-wise NOT operator in Python? [duplicate]

This question already has answers here:The tilde operator in Python(10 answers)Closed last year.Is there a function that takes a number with binary numeral a, and does the NOT? (For example, the funct…