Подтвердить что ты не робот

Понимание списка python double для

vec = [[1,2,3], [4,5,6], [7,8,9]]
print [num for elem in vec for num in elem]      <----- this

>>> [1, 2, 3, 4, 5, 6, 7, 8, 9]

Это меня обманывает.
Я понимаю, что elem - это списки внутри списка из for elem in vic
Я не совсем понимаю использование num и for num in elem в начале и в конце.

Как python интерпретирует это?
Какой порядок он смотрит?

4b9b3361

Ответ 1

Давайте сломаем его.

Простое понимание списка:

[x for x in collection]

Это легко понять, если мы разложим его на части: [A for B in C]

  • A - это элемент, который будет в результирующем списке
  • B - это каждый элемент коллекции C
  • C - это сама коллекция.

Таким образом, можно написать:

[x.lower() for x in words]

Чтобы преобразовать все слова в список в нижний регистр.


Это когда мы усложняем это следующим списком:

[x for y in collection for x in y] # [A for B in C for D in E]

Здесь происходит нечто особенное. Мы хотим, чтобы наш окончательный список включал элементы A, а элементы A находились внутри элементов B, поэтому мы должны рассказать о понимании этого списка.

  • A - это элемент, который будет в результирующем списке
  • B - это каждый элемент коллекции C
  • C - это сама коллекция
  • D - это каждый элемент в коллекции E (в этом случае также A)
  • E - это еще одна коллекция (в данном случае B)

Эта логика аналогична нормальной для цикла:

for y in collection:     #      for B in C:
    for x in y:          #          for D in E: (in this case: for A in B)
        # receive x      #              # receive A

Чтобы развернуть это и дать отличный пример + объяснение, представьте, что есть поезд.

Двигатель поезда (фронт) всегда будет там (результат понимания списка)

Тогда есть любое количество вагонов-вагонов, каждый вагон-фургон в форме: for x in y

Понимание списка может выглядеть так:

[z for b in a for c in b for d in c ... for z in y]

Какой будет такой регулярный цикл for:

for b in a:
    for c in b:
        for d in c:
            ...
                for z in y:
                    # have z

Другими словами, вместо того, чтобы спускать строку и отступы, в понимании списка вы просто добавляете следующий цикл в конец.

Чтобы вернуться к аналогии поезда:

Engine - Car - Car - Car... Tail

Что такое хвост? Хвост - особая вещь в понимании списка. Вам это не нужно, но если у вас есть хвост, хвост - это условие, посмотрите на этот пример:

[line for line in file if not line.startswith('#')] 

Это даст вам каждую строку в файле, если строка не начиналась с хэштега (#), другие просто пропущены.

Трюк с использованием "хвоста" поезда состоит в том, что он проверяется на наличие True/False одновременно с вашим окончательным "двигателем" или "результатом" из всех циклов, приведенный выше пример в регулярном for-loop будет выглядеть так:

for line in file:
    if not line.startswith('#'):
        # have line

обратите внимание: Хотя по моей аналогии с поездом в конце поезда есть только "хвост", состояние или "хвост" может быть после каждого "автомобиля" или цикла...

например:

>>> z = [[1,2,3,4],[5,6,7,8],[9,10,11,12]]
>>> [x for y in z if sum(y)>10 for x in y if x < 10]
[5, 6, 7, 8, 9]

В регулярном для цикла:

>>> for y in z:
    if sum(y)>10:
        for x in y:
            if x < 10:
                print x

5
6
7
8
9

Ответ 2

Из документации по пониманию списка:

Когда предоставляется представление списка, оно состоит из одного выражения, за которым следует по крайней мере одно предложение for и ноль или более for или if. В этом случае элементами нового списка являются те, которые будут создаваться путем рассмотрения каждого из предложений if или block, вложенных слева направо, и вычисления выражения для создания элемента списка каждый раз, когда достигается самый внутренний блок.

Другими словами, притворитесь, что петли for вложены. Чтение слева направо, ваше понимание списка может быть вложено как:

for elem in vec:
    for num in elem:
        num           # the *single expression* from the spec

где понимание списка будет использовать этот последний, самый внутренний блок как значения результирующего списка.

Ответ 3

Ваш код равен:

temp = []
for elem in vec:
    for num in elem:
        temp.append(num)