Копирование Python через назначение? - PullRequest
42 голосов
/ 13 марта 2010

Я ожидаю, что следующий код просто инициализирует словари dict_a, dict_b и dict_c. Но это выглядит как копия сквозного эффекта:

dict_a = dict_b = dict_c = {}
dict_c['hello'] = 'goodbye'

print dict_a
print dict_b
print dict_c

Как видите, результат выглядит следующим образом:

{'hello': 'goodbye'}
{'hello': 'goodbye'}
{'hello': 'goodbye'}

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

{}
{}
{'hello': 'goodbye'}

Ответы [ 4 ]

41 голосов
/ 13 марта 2010

Это потому, что в Python переменные (имена) являются просто ссылками на отдельные объекты. Когда вы присваиваете dict_a = dict_b, вы действительно копируете адрес памяти (или указатель, если хотите) из dict_b в dict_a. Есть еще один экземпляр этого словаря.

Чтобы получить желаемое поведение, используйте либо метод dict.copy, либо используйте copy.deepcopy, если в вашем диктанте могли быть вложенные или другие вложенные объекты.

>>> a = {1:2}
>>> b = a.copy()
>>> b
{1: 2}
>>> b[3] = 4
>>> a
{1: 2}
>>> b
{1: 2, 3: 4}
>>> 
8 голосов
/ 15 марта 2010

Даже если

>>> dict_a, dict_b, dict_c = {}, {}, {}

- правильный путь в большинстве случаев, когда он получает больше 3, это выглядит странно

Представьте

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}

В тех случаях, когда я хочу инициализировать более 3 вещей, я использую

>>> a, b, c, d, e, f, = [dict() for x in range(6)]

Внимание : Не использовать [{} for x in range(6)]

2 голосов
/ 13 марта 2010

Как уже говорил Данбен, вы просто копируете один и тот же dict в 3 переменные, чтобы каждая ссылалась на один и тот же объект.

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

>>> dict_a, dict_b, dict_c = {}, {}, {}
>>> dict_c['hello'] = 'goodbye'
>>> print dict_a
{}
>>> print dict_b
{}
>>> print dict_c
{'hello': 'goodbye'}
>>>
1 голос
/ 13 марта 2010

Ваше первое назначение назначает один и тот же объект словаря для переменных dict_a, dict_b и dict_c. Это эквивалентно dict_c = {}; dict_b = dict_c; dict_a = dict_c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...