Ключевое различие между вашими двумя фрагментами заключается в том, что content['a']['v'] = 3
— это совершенно другая операция, чем content['a'] = 3
. В первом случае вы модифицируете внутренний словарь, изменяя его ключ v
. В последнем случае вы заменяете значение в словаре, не изменяя его.
Это сбивает с толку, когда все является словарем, поэтому давайте заменим словари переменными и экземплярами класса:
class Person:
def __init__(self, name):
self.name = name
# these two variables are represent your `content` dict
a = Person('Andy') # this variable represents `{'v': 1}`
b = Person('Belle') # this variable represents `{'v': 2}`
# the equivalent of `d1['k1'].update(content)` is a simple assignment
k1_a = a
# and the equivalent of `content['a']['v'] = 3` is changing a's name
a.name = 'Aaron'
# because k1_a and a are the same Person instance, this is reflected in k1_a:
print(k1_a.name) # output: Aaron
Ключевые моменты, на которые следует обратить внимание, заключаются в том, что
k1_a = a
не делает копию Person; аналогично тому, как d1['k1'].update(content)
не делает копию {'v': 1}
dict.
a.name = 'Aaron'
изменяет человека; аналогично тому, как content['a']['v'] = 3
изменяет внутренний словарь.
Эквивалент вашего второго фрагмента выглядит так:
a = 'Andy'
b = 'Belle'
k1_a = a
a = 'Aaron'
print(k1_a) # output: Andy
На этот раз ни один объект никогда не модифицируется. Все, что мы делаем, это перезаписываем значение переменной a
, точно так же, как content['a'] = 3
перезаписывает значение ключа a
в вашем словаре.
Если вы не хотите, чтобы изменения во внутренних словарях отражались в других словарях, вам нужно скопировать их с помощью copy.deepcopy
:
import copy
content = {'a': {'v': 1}, 'b': {'v': 2}}
d1 = {'k1': {}}
d2 = {'k2': {}}
d1['k1'].update(copy.deepcopy(content))
print(d1)
content['a']['v'] = 3
content['b']['v'] = 4
d2['k2'].update(copy.deepcopy(content))
print(d2)
print(d1)
# output:
# {'k1': {'a': {'v': 1}, 'b': {'v': 2}}}
# {'k2': {'a': {'v': 3}, 'b': {'v': 4}}}
# {'k1': {'a': {'v': 1}, 'b': {'v': 2}}}
person
Aran-Fey
schedule
21.05.2018
dict
является изменяемым объектом, аint
неизменяемым. Это заставляет python обрабатывать их по-разному. То же самое произошло бы, если бы контент былlist
(изменчивым). - person zipa   schedule 21.05.2018content
)? - person Mateen Ulhaq   schedule 21.05.2018dict
, а во втором — наint
. Что сбивает с толку, так это вложенный характер этих словарей, но, тем не менее, в фоновом режиме все состоит из набора указателей, которые разрешаются после вызова. - person zipa   schedule 21.05.2018