2016-12-05 4 views
2

Если вы сделаете это список понимание:описаний списков и одна линия для петель

squares = [x**2 for x in range(100000)] 

Было бы занять много памяти, так что вы могли бы сделать то же самое с помощью генератора:

squares = (x**2 for x in range(100000)) 

Теперь давайте скажем, я хочу использовать одну линию контура для печати всех этих квадратов:

[print(square) for square in squares] 

Мой вопрос:: Печатает ли этот способ создания списка (это похоже на понимание списка)? Если да, сохраняет ли этот список в памяти? (Если это произойдет, это не имело бы никакого смысла использовать генератор при создании squares, потому что те будут получать хранится в другом списке так или иначе.) И еще одно: если вы сделаете это:

[1, 2, 3, 4, 5, 6] 

без назначения его к любой переменной, сохраняются ли эти значения в памяти?

ответ

3

без присвоения его имени в списке не будут храниться в памяти, так как нет никакой ссылки держа его (первоначально память будет выделено для него, но он сразу освобождается, так как (C) Python может видеть, что вы его не используете *).

Кроме того, печать с:

[print(square) for square in squares] 

крайне неэффективно; вы используете понимание списка только для побочного эффекта , который содержит результат вызова функции (его возвращаемое значение).

Это значит, что в итоге у вас есть страница None, созданное , просто для того, чтобы его бросить, не так много использовать его.

Вам лучше использовать генератор с петлей for, как предлагает @ user312016 в его ответе. Генератор будет работать по требованию, и никакой дополнительный список не будет создан.

* В интерактивном режиме все по-другому, так как вы используете имя _, используемое как имя самого последнего вычисляемого выражения. Там список сохраняется в памяти, пока следующее выражение не переопределит значение, прикрепленное к _.

+1

Важное замечание: они все равно будут созданы в памяти интерпретатором, а затем уничтожены сборщиком мусора, поскольку недостаток ссылок. – user312016

+1

Да да @ user312016, вот почему я написал * «Первоначально память будет выделена, но она сразу же освобождается, поскольку Python может видеть, что вы ее не используете» * :-). Я интерпретировал вопрос OPs «хранимый в памяти» как вопрос о том, сохраняется ли память в памяти * после того, как * оператор выполнил.(в интерактивном режиме '_' хранит его, но это исключение) –

+0

Woops, я пропустил эту часть – user312016

2

Да, это создает list и хранится в памяти, вы не должны использовать списки, как одиночные строки для циклов, это не то, для чего они предназначены.

Вы можете сделать:.

for square in (x**2 for x in range(100000)): 
    print(square)