簡體   English   中英

Python:嵌套字典一次更改所有值

[英]Python: nested dictionary is changing all values at once

我需要生成嵌套字典,所以我寫了 function create_nested

def create_nested():
    key_dict = {}
    for key in ['key1', 'key2']:
        key_dict[key] = 0

    nested_dict = {}
    for dictionary in ['dict1', 'dict2']:
        nested_dict[dictionary] = key_dict
    return nested_dict

這將始終返回如下內容:

{'dict1': {'key1': 0, 'key2': 0}, 'dict2': {'key1': 0, 'key2': 0}}

當嘗試以這種方式更改其中一個值時:

x=create_nested()
x['dict1']['key2'] = 2

它給了我{'dict1': {'key1': 0, 'key2': 2}, 'dict2': {'key1': 0, 'key2': 2}}

而不是{'dict1': {'key1': 0, 'key2': 2}, 'dict2': {'key1': 0, 'key2': 0}}

我究竟做錯了什么?

When you assign the key_dict to multiple values in nested_dict, they will refer to the same object in memory (I hope my terminology is correct. Python is Pass-by-object-reference, full explaination here https://robertheaton.com/2014 /02/09/pythons-pass-by-object-reference-as-explained-by-philip-k-dick/

for dictionary in ['dict1', 'dict2']:
        nested_dict[dictionary] = key_dict
    return nested_dict

現在,如果我更改nested_dict['dict1'],我將更改nested_dict['dict2'] 知道的同一個memory。 一般來說,知道哪些類型是可變的,並期望它們在另一個對它的引用改變時改變。

對只有不可變值的字典的簡單修復是:

for dictionary_name in ['dict1', 'dict2']: # The variable name dictionary for a string is very confusing, so changing that.
        # create a new dictionary in memory
        nested_dict[dictionary_name] = {k: v for k, v in key_dict.items()}
    return nested_dict

如果您在 key_dict 中具有可變的潛在值,那么您必須進行深層復制。 https://docs.python.org/3/library/copy.html

您的dict1dict2鍵引用之前創建的相同dict object ,因此對其執行的任何更改都會影響兩個鍵的值。

如果你想為你的鍵分配兩個不同的dicts ,你應該復制它:

import copy
def create_nested():
    key_dict = {}
    for key in ['key1', 'key2']:
        key_dict[key] = 0
        nested_dict = {}
    for dictionary in ['dict1', 'dict2']:
        nested_dict[dictionary] = copy.deepcopy(key_dict)

deepcopy將遞歸地復制字典中的所有元素,並為您創建一個獨立的副本,因此對其執行的任何更改都只會影響它自己。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM