I want to understand nested list comprehension.
Below, I listed a list comprehension expression and their for loop equivalent.
I wonder if my understanding is correct on those.
[(min([row[i] for row in rows]),max([row[i] for row in rows])) for i in range(len(rows))]
es equivalente a
result= for i in range(len(rows)): 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 may generalize, I guess
[exp2([exp1 for x in xSet]) for y in ySet]
form can be translated to the following. (I hope I'm correct on this)
result= for y in ySet: innerResult = for x in xSet: innerResult.append(exp1) exp2Result = exp2(innerResult) result.append(exp2Result)
For simpler case,
[exp1 for x in xSet for y in ySet]
es igual a
result= for x in xSet: for y in ySet: result.append(exp1)
[[exp1 for x in xSet] for y in ySet]
es igual a
result= for y in ySet: innerResult= for x in xSet: innerResult.append(exp1) result.append(innerResult)
I asked a similar question on Equivalente para expresión de bucle para comprensión de listas complejas
The answers given there reconstruct the form after understanding what it does internally.
I'd like to know how it works systematically so I can apply the concept to other slightly varying examples.
preguntado el 08 de noviembre de 11 a las 11:11
Indeed, you are correct. This is described in detail in the Expressions section in the Python Language Reference.
Note especially the order of nesting of several
fors in a single list comprehension, which is always 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]
La respuesta corta es: yes, you are correct in your understanding.
There's only a catch: the way you normally use nested list comprehension in python code is to operate on multidimensional arrays.
A typical example is when you operate on 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 the "nesting" works by operating on each dimension of the matrix.
In the examples you provided, it seems that
ySet [unfortunate name btw, as conjuntos are one of the types provided with python] is just a generic counter, which makes a bit harder to follow what is going on 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))] [(1, 10), (2, 20), (3, 30)]
Es posible que desee mirar en el Código Postal función incorporada:
>>> zip(rows, rows) [(1, 10), (2, 20), (3, 30)]
or for maximum brevity and elegance:
>>> zip(*rows) [(1, 10), (2, 20), (3, 30)]