簡體   English   中英

如何更新嵌套在另一個中的字典?

[英]How to update a dict nested in another?

我有以下原始字典:

{'data_extraction': {'if_extraction': False,
  'path_data': 'data_extraction/extractions.sql',
  'set_params': {'START_DT': "'201901'",
   'END_DT': "'202104'"
                         },
  'calibration': True,
  'target_variable': 'unsure'}}

我想用以下字典替換 set params 位:

dict1= {'set_params': {'START_DT': "'201001'",
   'END_DT': "'201004'"
}}

我從一個類似的問題中獲取了這段代碼:

import collections.abc

def update(d, u):
    for k, v in u.items():
        if isinstance(v, collections.abc.Mapping):
            d[k] = update(d.get(k, {}), v)
        else:
            d[k] = v
    return d

update(original,dict1)

將其應用於上述內容,我得到:

 {'data_extraction': {'if_extraction': False,
          'path_data': 'data_extraction/extractions.sql',
          'set_params': {'START_DT': "'201901'",
           'END_DT': "'202104'"
                                 },
          'calibration': True,
          'target_variable': 'unsure'},
           'set_params': {'START_DT': "'201001'",
            'END_DT': "'201004'" }}

因此,它沒有替換,而是在末尾附加了替換字典。 如何更新字典中的值,以便如果我傳遞另一個字典,就像我使用dict1 ,它會替換它? 我究竟做錯了什么?

這些天 Python 字典有一個更新方法可以從另一個字典更新。 請務必指定要更新和更新的適當字典!

original['data_extraction']['set_params'].update(dict1['set_params'])

或者可能

original['data_extraction'].update(dict1)

如果 dict1 中除了 'set_params' 之外還有其他鍵,並且您也想更新這些鍵。

recursive functiondict.update()一起使用。 這樣您就不必在多級字典的情況下對鍵進行分隔。

def update_dict(source_dict, dict1):
    for key in source_dict:
        if key in dict1.keys():
            source_dict.update(dict1)
        elif isinstance(source_dict[key],dict):
            update_dict(source_dict[key], dict1)


source_dict = {'data_extraction': {'if_extraction': False,
      'path_data': 'data_extraction/extractions.sql',
      'set_params': {'START_DT': "'201901'",
       'END_DT': "'202104'"},
      'calibration': True,
      'target_variable': 'unsure'}}

dict1= {'set_params': {'START_DT': "'201001'",
   'END_DT': "'201004'"
}}

update_dict(source_dict, dict1)

print(source_dict)

>> 
{'data_extraction': {'if_extraction': False,
  'path_data': 'data_extraction/extractions.sql',
  'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"},
  'calibration': True,
  'target_variable': 'unsure'}}

你幾乎就在那里......在這個實現中,我使用 deepcopy() 來避免覆蓋原始字典。

from copy import deepcopy

def update(d, u):
    r = deepcopy(d)
    for k, v in r.items():
        if type(v) is dict:
            for _k, _v in v.items():
                if _k in u:
                    r[k][_k] = u[_k]
        elif k in u:
            r[k] = u[k]
    return r


a = {'data_extraction':{'if_extraction': False,
                         'path_data': 'data_extraction/extractions.sql',
                         'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"},
                         'calibration': True,
                         'target_variable': 'unsure'}
     }

b = {'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}}

c = update(a, b)

print(a, '\n')
print(b, '\n')
print(c, '\n')

Output:

{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201901'", 'END_DT': "'202104'"}, 'calibration': True, 'target_variable': 'unsure'}} 

{'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}} 

{'data_extraction': {'if_extraction': False, 'path_data': 'data_extraction/extractions.sql', 'set_params': {'START_DT': "'201001'", 'END_DT': "'201004'"}, 'calibration': True, 'target_variable': 'unsure'}}

在字典中,當您向不存在的鍵添加某些內容時,會附加它,然后添加內容。 如果您想替換某些密鑰,則必須先將其刪除。
使用popyourdict.pop ("key to delete") ),然后您可以正常添加另一個鍵。

您需要讓遞歸 function 檢查每個(嵌套)字典以查看它是否包含需要替換的鍵( target_key )。 在下面的代碼中,這是從傳遞給update() function 的替換字典參數new_dict中檢索的。 這只需要執行一次,因此有一個nested_update() function 可以進行實際替換。

import collections.abc

original = {
  "data_extraction": {
    "if_extraction": False,
    "path_data": "data_extraction/extractions.sql",
    "set_params": {
      "START_DT": "'201901'",
      "END_DT": "'202104'"
    },
    "calibration": True,
    "target_key_variable": "unsure"
  }
}

dict1 = {
  "set_params": {
    "START_DT": "'201001'",
    "END_DT": "'201004'"
  }
}


def update(d, new_dict):
    target_key, new_value = list(new_dict.items())[0]

    def nested_update(d, new_dict):
        for key, value in d.items():
            if key == target_key:
                d[key] = new_value
            elif isinstance(value, collections.abc.Mapping):
                d[key] = nested_update(value, new_dict)
        return d

    nested_update(d, new_dict)
    return d

update(original, dict1)

import json
print(json.dumps(original, indent=2))  # Pretty-print result.

Output:

{
  "data_extraction": {
    "if_extraction": false,
    "path_data": "data_extraction/extractions.sql",
    "set_params": {
      "START_DT": "'201001'",
      "END_DT": "'201004'"
    },
    "calibration": true,
    "target_key_variable": "unsure"
  }
}

暫無
暫無

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

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