Понимание вложенного списка
Я хочу понять понимание вложенного списка.
Ниже я перечислил выражение для понимания списка и их эквивалент цикла.
Интересно, правильно ли я понимаю это.
Например,
[(min([row[i] for row in rows]),max([row[i] for row in rows]))
for i in range(len(rows[0]))]
эквивалентно
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)
Если я могу обобщить, я думаю,
[exp2([exp1 for x in xSet]) for y in ySet]
Форма
может быть переведена на следующее. (Надеюсь, я прав.)
result=[]
for y in ySet:
innerResult =[]
for x in xSet:
innerResult.append(exp1)
exp2Result = exp2(innerResult)
result.append(exp2Result)
Для более простого случая
[exp1 for x in xSet for y in ySet]
равно
result=[]
for x in xSet:
for y in ySet:
result.append(exp1)
тогда,
[[exp1 for x in xSet] for y in ySet]
равно
result=[]
for y in ySet:
innerResult=[]
for x in xSet:
innerResult.append(exp1)
result.append(innerResult)
Я задал аналогичный вопрос в Эквивалент выражения цикла для комплексного понимания списка
Ответы, полученные там, восстанавливают форму после понимания того, что она делает внутри.
Я хотел бы знать, как это работает систематически, поэтому я могу применить концепцию к другим слегка меняющимся примерам.
Ответы
Ответ 1
Короткий ответ: да, вы правы в своем понимании.
Есть только улов: то, как вы обычно используете понимание вложенного списка в коде python, должно работать с многомерными массивами.
Типичным примером является работа с матрицами:
>>> 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]]
Как вы можете видеть, что "вложенность" работает, работая над каждым измерением матрицы.
В приведенных примерах, кажется, что ySet
[неудачное имя btw, поскольку sets - один из типов, предоставляемых с помощью python] это всего лишь общий счетчик, что делает немного сложнее следить за тем, что происходит под капотом.
Что касается вашего первого примера:
>>> 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)]
Возможно, вы захотите изучить встроенную функцию zip:
>>> zip(rows[0], rows[1])
[(1, 10), (2, 20), (3, 30)]
или для максимальной краткости и элегантности:
>>> zip(*rows)
[(1, 10), (2, 20), (3, 30)]
НТН!
Ответ 2
Действительно, вы правы. Это подробно описано в разделе Выражения в Справочнике по языку Python.
Обратите внимание, в частности, порядок вложенности нескольких for
в одном понимании списка, который всегда слева направо:
>>> 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]