2011-12-22 2 views
2

Вот простой код, который выполняет операции по спискам:странное поведение со списком словарей в Python

>>> a = [0] * 5 
>>> a 
[0, 0, 0, 0, 0] 
>>> a[0] = 5 
>>> a 
[5, 0, 0, 0, 0] 
>>> 

На данный момент ничего ненормального.

Теперь я пытаюсь сделать то же самое со списком словарей вместо списка целых чисел:

>>> a = [{}] * 5 
>>> a 
[{}, {}, {}, {}, {}] 
>>> a[0]['b'] = 4 
>>> a 
[{'b': 4}, {'b': 4}, {'b': 4}, {'b': 4}, {'b': 4}] 
>>> 

Я не понимаю, почему все элементы моего списка модифицируются ...

Может ли кто-нибудь сказать мне, почему? А также обеспечить обходное решение?

+1

См [это] (http://stackoverflow.com/a/8240157/566644) ответ для объяснения углубленному этого поведения. –

+0

Возможный дубликат [Изменение стоимости на нескольких позициях в списке списка при попытке изменения в одном месте] (http://stackoverflow.com/questions/8240054/value-changing-at-multiple-positions-in-a- list-of-list-when-try-to-change-at) – geoffspear

ответ

9

Это не странно.


Обход:

a = [{} for i in xrange(5)] 

[…] * 5 создает один и список из пяти указателей на этой .

0 - неизменяемое целое число. Вы не можете изменить его, вы можете просто заменить его другим целым числом (например, a[0] = 5). Тогда это другое целое число.

{} - это изменяемый словарь. Вы его изменяете: a[0]['b'] = 4. Это всегда один и тот же словарь.

+1

+1 Это создает список из 5 словарей, а не список из 5 ссылок на словарь. Зачем? Гвидо сделал это так! Доступ к словарям осуществляется по ссылке. –

+0

Изменчивость не имеет к этому никакого отношения. 'a [0] = {'b': 4}' работал бы отлично; ключ заключается в том, что исходный код не пытается заменить словарь. – geoffspear

+0

-1: Это не «обходной путь». Это «правильное использование изменяемых объектов». –

0

Попробуйте это,

a = map([].append, {} for i in xrange(3)) 
Смежные вопросы