Может ли кто-нибудь объяснить поведение пустых диктов в выражениях генератора Python?

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

In [46]: l = ({} for _ in range(6))

In [47]: [ id(i) for i in l]
Out[47]:
[4371243648, # A
 4371245048, # B
 4371243648, # A
 4371245048, # B
 4371243648, # etc.
 4371245048]

Что здесь удивительно, так это то, что у нас, кажется, нет четко определенного поведения: dict не является ни новым каждый раз, ни одной и той же ссылкой каждый раз.

Кроме того, мы получили это странное поведение (между этими двумя фрагментами в интерпретаторе не выполнялся код).

In [48]: m = ({} for _ in range(6))

In [49]: [ id(i) for i in m]
Out[49]:
[4371154376, # C
 4371245048, # B (same B as above!)
 4371154376, # C
 4371245048, # B
 4371154376,
 4371245048]

Кто-нибудь может объяснить такое поведение? Использование списков (l = [{} for _ in range(6)]) показывает разные адреса для каждого словаря.


person sitaktif    schedule 10.03.2015    source источник
comment
Этот вопрос может дать вам хорошее представление о том, что происходит   -  person bvidal    schedule 10.03.2015
comment
Вы читали id() документацию по функциям? Вы пропустили что-то важное там.   -  person Martijn Pieters    schedule 10.03.2015
comment
@MartijnPieters Я не удивлен id() повторным использованием одного и того же номера. Меня удивило лицо, потому что оно повторно использовало один и тот же номер, хотя я сохранил ссылку на него (что было моей ошибкой).   -  person sitaktif    schedule 10.03.2015
comment
@sitaktif: правильно, вы не сохраняете никаких ссылок на {} объекты, которые вы создаете; генератор производит их, но не ссылается на них впоследствии.   -  person Martijn Pieters    schedule 10.03.2015
comment
@sitaktif: я думаю, вы ошиблись здесь: словарь не является ни новым каждый раз, ни одной и той же ссылкой каждый раз. Каждый раз является новым словарем; левое выражение в выражении генератора оценивается заново на каждой итерации.   -  person Martijn Pieters    schedule 10.03.2015
comment
@MartijnPieters абсолютно   -  person sitaktif    schedule 11.03.2015


Ответы (1)


Словари уничтожаются, как только на них больше не ссылается генератор. Вы сравниваете идентификаторы мертвых объектов, и идентификаторы можно использовать повторно.

person Kevin    schedule 10.03.2015
comment
Это именно то, что я упустил - то, что с генератором я теряю ссылку на элемент. Спасибо! - person sitaktif; 10.03.2015