python: добавление словаря в список - я вижу указатель, похожий на поведение

88

В интерпретаторе Python я пробовал следующее:

>>>
>>> a = []
>>> b = {1:'one'}
>>> a.append(b)
>>> a
[{1: 'one'}]
>>> b[1] = 'ONE'
>>> a
[{1: 'ONE'}]
>>>

Здесь, после добавления словаря «b» к списку «a», я меняю значение, соответствующее ключу 1 в словаре «a». Каким-то образом это изменение отражается и в списке. Когда я добавляю словарь в список, разве я не просто добавляю значение словаря? Похоже, я добавил указатель на словарь к списку, и, следовательно, изменения словаря также отражаются в списке.

Я не хочу, чтобы изменение отражалось в списке. Как это сделать?

Спасибо за уделенное время!

neo29
источник
Чехов Это не словарь «б» , это либо словарь «б», либо словарь имени «б» . Кстати, вы написали с ошибкой: «Я меняю значение, соответствующее ключу 1 в словаре 'a'» Нет, в словаре b. Что касается вашего удивления: список не содержит значений, он содержит объекты, поскольку в Python все является объектами. Или, точнее, список содержит ссылки на объекты.
eyquem 09
Чехов. Вы также должны увидеть этот вопрос: ( stackoverflow.com/questions/5242933/… )
eyquem
@eyquem спасибо за ваш комментарий. Я публиковал это в спешке. Мои извенения.
neo29 09
Чехов. Это не упрек, это информация. Кстати, если мой ответ будет чем-то полезным, за него можно проголосовать. Кроме того, вы можете выбрать «принять» один ответ среди ответов, нажав на полосу в форме шеврона под счетчиком баллов слева от одного ответа, вы получите 25 баллов. Или вы можете не отвечать ни на один вопрос.
eyquem 09

Ответы:

145

Вы правы в том, что в вашем списке есть ссылка на исходный словарь.

a.append(b.copy()) должен сделать свое дело.

Имейте в виду, что это делает мелкую копию. Альтернативой является использование copy.deepcopy(b), которое создает глубокую копию.

NPE
источник
6
здорово! Меня на этом долго блокировали
Ясин
2
это сносило меня с ума около получаса, пока я не сдался и не решил проверить стек.
FlyingZebra1
35

Также с dict

a = []
b = {1:'one'}

a.append(dict(b))
print a
b[1]='iuqsdgf'
print a

результат

[{1: 'one'}]
[{1: 'one'}]
Eyquem
источник
Не уверен, что это достаточно быстро, как copy (), но кажется быстрее, чем deepcopy (). Возможно, со сложной схемой словаря он будет близок к deepcopy (), потому что dict () создает новый словарь.
selotec