![](/img/trans.png)
[英]How to correctly update the values of list types in a Python nested dictionary?
[英]How do I correctly update nested dictionary values from a list in python?
請告訴我我做錯了什么!
我希望從列表中更新字典中的條目。 這是我的(簡化的)字典和列表:
scene_dict = {0: {'speaker': None, 'listener': None}, 1: {'speaker': None, 'listener': None}}
speaker_list = ["Horatio", "Marcellus"]
我想達到以下結果:
scene_dict = {0: {'speaker': "Horatio", 'listener': None}, 1: {'speaker': "Marcellus", 'listener': None}}
這似乎是一個直截了當的問題。
為了獲得所需的結果,我執行以下操作:
for i, j in enumerate(scene_dict):
scene_dict[j]["speaker"] = speaker_list[i]
然后給出我想要的結果,是的!
print(scene_dict)
{0: {'speaker': 'Horatio', 'listener': None}, 1: {'speaker': 'Marcellus', 'listener': None}}
那么,“問題出在哪里?” 你可能會問。 好吧,實際上,我正在處理的名單要長得多。 因此,我的字典需要相應地更長,但它具有完全相同的形式。 自然地,我不想通過明確地寫下來來定義我的字典。 我需要以某種方式生成它,我這樣做如下:
para_dict = {"speaker": None, "listener": None}
scene_dict = {}
for k in range(0,2):
scene_dict[k] = para_dict
這個“似乎”工作正常,並且“似乎”給出了與我開始時完全相同的字典:
print(scene_dict)
{0: {'speaker': None, 'listener': None}, 1: {'speaker': None, 'listener': None}}
但是,當我現在在我的(“完全相同”)生成的字典上重新運行上面完全相同的 for 循環時,為了將我的列表的元素傳輸到字典中的值
for i, j in enumerate(scene_dict):
scene_dict[j]["speaker"] = speaker_list[i]
我得到一個不同的(錯誤的)結果:
print(scene_dict)
{0: {'speaker': 'Marcellus', 'listener': None}, 1: {'speaker': 'Marcellus', 'listener': None}}
這次 for 循環顯然同時將兩個字典鍵(“speaker”)等同於列表中的第一個名字,然后將兩個鍵與列表中的第二個名字等同,即它與 Horatio 等同,然后與 Marcellus 等同.
我很困惑。 我做錯什么了? 我怎樣才能做得更好?
任何意見,將不勝感激。
啊你被 python objects are all references trick 騙了!
對於每個 object、 dict
、 array
、 Object
等的上下文。 綁定到變量作為存儲在 memory 中的實際 object 的引用或指針。當你做類似的事情時
obj = {"Hello" : "I'm an object"}
obj2 = obj
您沒有制作obj
的副本並將其存儲在obj2
中。 obj2
只是再次引用obj
。 如果您使用id
function打印obj
和obj2
的 memory 地址,您將獲得相同的地址
現在以你的例子為例,當你這樣做時
para_dict = {"speaker": None, "listener": None}
scene_dict = {}
for k in range(0,2):
scene_dict[k] = para_dict
您將對scene_dict
的相同引用分配給para_dict
中的每個條目。 那是,
{
0 : {"speaker" : None, "listener" : None},
1 : {"speaker" : None, "listener" : None}
}
實際上是
{
0 : para_dict, # These are actually the same object!
1 : para_dict
}
所以當你修改你的scene_dict
時,
for i, j in enumerate(scene_dict):
scene_dict[j]["speaker"] = speaker_list[i]
您修改已分配的para_dict
的每個實例。 所以通過循環你會得到。
start | {0: {'speaker': None, 'listener': None}, 1: {'speaker': None, 'listener': None}}
1st iter | {0: {'speaker': 'Horatio', 'listener': None}, 1: {'speaker': 'Horatio', 'listener': None}}
2nd iter | {0: {'speaker': 'Marcellus', 'listener': None}, 1: {'speaker': 'Marcellus', 'listener': None}}
現在修復非常簡單,而不是分配para_dict
只是每次都制作字典。
scene_dict = {}
for k in range(0,2):
scene_dict[k] = {"speaker": None, "listener": None}
這將在循環的每次迭代中創建一個新字典,而不是對已創建字典的引用。 如果您的para_dict
變得復雜,您可以查看copy
function 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.