Копировать Python через назначение?
Я ожидаю, что следующий код просто инициализирует словари 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'}
Ответы
Ответ 1
Это потому, что в Python переменные (имена) являются просто ссылками на отдельные объекты. Когда вы назначаете dict_a = dict_b
, вы действительно копируете адрес памяти (или указатель, если хотите) от dict_b
до dict_a
. Существует еще один экземпляр этого словаря.
Чтобы получить желаемое поведение, используйте либо метод dict.copy
, либо используйте copy.deepcopy
, если ваш dict может иметь вложенные dicts или другие вложенные объекты.
>>> a = {1:2}
>>> b = a.copy()
>>> b
{1: 2}
>>> b[3] = 4
>>> a
{1: 2}
>>> b
{1: 2, 3: 4}
>>>
Ответ 2
Несмотря на то, что
>>> 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)]
Ответ 3
Как ранее говорил данбен, вы просто копируете один и тот же dict в 3 переменные, чтобы каждый из них ссылался на один и тот же объект.
Чтобы получить нужное поведение, вы должны указать другой dict в каждой переменной:
>>> dict_a, dict_b, dict_c = {}, {}, {}
>>> dict_c['hello'] = 'goodbye'
>>> print dict_a
{}
>>> print dict_b
{}
>>> print dict_c
{'hello': 'goodbye'}
>>>
Ответ 4
Ваше первое назначение присваивает тот же словарь объект переменным dict_a, dict_b и dict_c. Это эквивалентно dict_c = {}; dict_b = dict_c; dict_a = dict_c.