Python:字典字典字典更新数据所有数据,而不仅仅是指定的数据

Python:字典字典字典更新数据所有数据,而不仅仅是指定的数据,python,dictionary,Python,Dictionary,我在使用字典中的字典时遇到问题,可以通过下面的代码来描述: Dic_A = {} Dic_B = {} Dic_A["A1"] = "1" Dic_A["A2"] = "2" Dic_B["AA"] = Dic_A print "Dic_B after : " + str(Dic_B) Dic_A["A1"] = "4" Dic_A["A2"] = "5" print "Dic_B before: " + str(Dic_B) Dic_B["AB"] = Dic_A print "

我在使用字典中的字典时遇到问题,可以通过下面的代码来描述:

Dic_A = {}
Dic_B = {}

Dic_A["A1"] = "1"
Dic_A["A2"] = "2"

Dic_B["AA"] = Dic_A

print "Dic_B after : " + str(Dic_B)

Dic_A["A1"] = "4"
Dic_A["A2"] = "5"

print "Dic_B before: " + str(Dic_B)

Dic_B["AB"] = Dic_A

print "Dic_B after : " + str(Dic_B)
我得到的结果是:

Dic_B after : {'AA': {'A1': '1', 'A2': '2'}}

Dic_B before: {'AA': {'A1': '4', 'A2': '5'}}

Dic_B after : {'AA': {'A1': '4', 'A2': '5'}, 'AB': {'A1': '4', 'A2': '5'}}
为什么在我更新Dic_A时Dic_B[“AA”]会更新?我该如何解决这个问题呢

提前感谢:-)

尼克

为什么在我更新Dic_A时Dic_B[“AA”]会更新?我该如何解决这个问题呢

因为
Dic_B[“AA”]
Dic_A
。这就是Dic_B[“AA”]=Dic_A的意思。请尝试打印(Dic_B[“AA”]是Dic_A。您会注意到它打印的是
True
,因为它们实际上是同一个对象

如果不想存储对同一词典的两个引用,则需要创建新对象,而不是在旧对象中重新分配值

dic_a = {} # new dictionary
dic_a['A1'] = '1'
dic_a['A2'] = '2'
dic_b['AA'] = dic_a # store dic_a in dic_b

dic_a = {} # CREATE a new dictionary and point the name dic_a to it.

dic_a['A1'] = '1'
dic_a['A2'] = '2'
dic_b['AA'] = dic_a # store the NEW dic_a in dic_b

当然,有更好的方法可以做到这一点,你也可以做一些事情来简化你的生活,比如更好地命名字典。例如,你可以利用
dict
类型可以将字典复制到新的实例中,所以如果你想继续重用源字典,你可以这样做,而且总是这样将副本插入父词典:

# put stuff in dic_a...
dic_b['AA'] = dict(dic_a) # put a copy of dic_a into dic_b

# put different stuff in dic_a...
dic_b['AB'] = dict(dic_a) # put a copy of the altered dic_a into dic_b
这就是他们所说的最小惊奇原则。只是开玩笑而已

这样做:

Dic_B["AA"] = Dic_A
print(Dic_B['AA'] is Dic_A)
您将在输出中看到
True
。这意味着您认为通过值复制的对象是通过引用复制的,如果您在一个位置修改它,它也将在另一个位置被修改

也来看看

有很多解决方案:

from copy import copy
Dic_B["AA"] = copy(Dic_A)

所有的解决方案都可以解决您的问题,但是,只有第二个可以通过值(而不是引用)从
Dic_A
复制值。例如,
Dic_A
可能包含一些
列表
对象,只有
deepcopy
可以通过值复制,其他解决方案可以通过引用复制:

>>> from copy import copy, deepcopy
>>> Dic_A = {'key': ['v', 'a', 'l', 'u', 'e']}
>>> Dic_B = copy(Dic_A) 
>>> Dic_B is Dic_A # Different `dict` objecst, but ...
False
>>> Dic_B['key'] is Dic_A['key'] # The same `list` object
True
>>> Dic_B = deepcopy(Dic_A)
>>> Dic_B is Dic_A # Different `dict` objects
False
>>> Dic_B['key'] is Dic_A['key'] # and `list` objects
False

因此,我认为在需要按值复制整个对象的情况下更好。

像这样的问题太多了:/抱歉,我无法通过搜索找到任何东西(很难知道真正要搜索什么)。如果您能为我提供一个有用的解决方案/解释。谢谢。如果您想要一本其他词典的词典,那么这就是您所期望的,不是吗?您创建了词典a并将其放在B中,似乎您想要这种行为。如果您想要的是一本与词典B中的词典a类似的词典(副本),然后你应该参考贴出的三个正确答案。Python所做的对我来说似乎是违反直觉的,所以做了一些研究-对于其他感兴趣的人来说,这是一个非常好的解释:感谢帮助和解释-非常感谢:-)字典是如何通过引用复制的有点奇怪,但是变量是按值复制的——我相信这是有充分理由的@尼克,这比你想象的要一致。请参阅以获得非常好的解释。本质上,它与“按引用传递”或“按值传递”无关,而是(例如)字典是可变对象,而字符串不是。感谢您的帮助和解释-非常感谢:-)我最终使用了“deepcopy”,而不是尝试重新编写代码(这只是一个一次性的文本处理脚本-只要它能工作,就不必快速/漂亮)字典是如何通过引用复制的有点奇怪,但变量是通过值复制的-我相信这有一个很好的理由!?!“最小惊讶原则”:-@NickFromage补充了一点解释
Dic_B["AA"] = dict(Dic_A)
Dic_B["AA"] = {}
Dic_B["AA"].update(Dic_A) 
>>> from copy import copy, deepcopy
>>> Dic_A = {'key': ['v', 'a', 'l', 'u', 'e']}
>>> Dic_B = copy(Dic_A) 
>>> Dic_B is Dic_A # Different `dict` objecst, but ...
False
>>> Dic_B['key'] is Dic_A['key'] # The same `list` object
True
>>> Dic_B = deepcopy(Dic_A)
>>> Dic_B is Dic_A # Different `dict` objects
False
>>> Dic_B['key'] is Dic_A['key'] # and `list` objects
False