Understanding the nested list

I want to understand the understanding of a nested list. Below I have listed an expression for understanding the list and their equivalent loop.
I wonder if I understand this correctly.

For example,

[(min([row[i] for row in rows]),max([row[i] for row in rows])) for i in range(len(rows[0]))] 

equivalently

 result=[] for i in range(len(rows[0])): innerResult=[] for row in rows: innerResult.append(row[i]) innerResult2=[] for row in rows: innerResult2.append(row[i]) tuple=(min(innerResult), max(innerResult2)) result.append(tuple) 

If I can generalize, I think

 [exp2([exp1 for x in xSet]) for y in ySet] 
The form

can be translated into the following. (I hope I'm right.)

 result=[] for y in ySet: innerResult =[] for x in xSet: innerResult.append(exp1) exp2Result = exp2(innerResult) result.append(exp2Result) 

For a simpler case

 [exp1 for x in xSet for y in ySet] 

equally

 result=[] for x in xSet: for y in ySet: result.append(exp1) 

then,

 [[exp1 for x in xSet] for y in ySet] 

equally

 result=[] for y in ySet: innerResult=[] for x in xSet: innerResult.append(exp1) result.append(innerResult) 

I asked a similar question in Equivalent loop expressions for a comprehensive list comprehension
The answers received there restore the form after understanding what it does inside.
I would like to know how this works systematically, so I can apply the concept to other slightly changing examples.

+68
python list-comprehension nested
Nov 08 '11 at 11:38
source share
2 answers

Short answer: yes, you are right in your understanding .

There is only catch: the way you usually use nested list comprehension in python code should work with multidimensional arrays.

A typical example is working with matrices:

 >>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> [[el - 1 for el in row] for row in matrix] [[0, 1, 2], [3, 4, 5], [6, 7, 8]] 

As you can see, nesting works by working on each dimension of the matrix.

In the above examples, it seems that ySet [the bad name btw, since sets is one of the types provided with python] is just a general counter, which makes it a little harder to keep track of what happens under the hood.

As for your first example:

 >>> rows = ([1, 2, 3], [10, 20, 30]) >>> [(min([row[i] for row in rows]),max([row[i] for row in rows])) for i in range(len(rows[0]))] [(1, 10), (2, 20), (3, 30)] 

You might want to explore the built-in zip function:

 >>> zip(rows[0], rows[1]) [(1, 10), (2, 20), (3, 30)] 

or for maximum brevity and elegance:

 >>> zip(*rows) [(1, 10), (2, 20), (3, 30)] 

NTN!

+68
Nov 08 '11 at 12:19
source share

Indeed, you are right. This is described in detail in the Expressions section of the Python Language Reference .

Note, in particular, the nesting order of several for in one understanding of the list, which is always from left to right:

 >>> matrix = [[1, 2], [3, 4]] >>> [item for item in row for row in matrix] # oops! Traceback (most recent call last): File "<pyshell#1>", line 1, in <module> [item for item in row for row in matrix] NameError: name 'row' is not defined >>> [item for row in matrix for item in row] # nesting is in left-to-right order [1, 2, 3, 4] 
+68
Nov 08 '11 at 12:32
source share



All Articles