如何更改嵌套键的值
目标:我想要修改一个嵌套字典的值,但我事先并不知道这个字典的具体结构。
这里有一个示例输入字典:
example_dict = {
'key1': 'value1',
'key2': {
'key2a': 'value2a'
},
'key3': {
'key3a': {
'key3aa': 'value3aa',
'key3ab': 'value3ab',
'key3ac': 'value3ac'
},
'key3b': [
'value3b1',
'value3b2'
]
},
}
期望的输出:
example_dict = {
'key1': 'changed_value1',
'key2': {
'key2a': 'changed_value2a'
},
'key3': {
'key3a': {
'key3aa': 'changed_value3aa',
'key3ab': 'changed_value3ab',
'key3ac': 'changed_value3ac'
},
'key3b': [
'changed_value3b1',
'changed_value3b2'
]
},
}
我尝试过的:首先,我在递归地查找字典中的键和值。
def recursive(src, so_far=()):
if isinstance(src, dict):
for key, value in src.items():
yield from recursive(value, so_far + (key,))
elif isinstance(src, list):
for item in src:
yield from recursive(item, so_far)
else:
yield ' '.join(so_far + (src,))
for line in recursive(example_dict):
print(line)
这段代码输出:
key1 value1
key2 key2a value2a
key3 key3a key3aa value3aa
key3 key3a key3ab value3ab
key3 key3a key3ac value3ac
key3 key3b value3b1
key3 key3b value3b2
现在我知道了字典的结构,我想要编辑这些值。
但我在这里遇到了困难。
我知道可以通过以下方式来改变字典的值:
example_dict['key1'] = 'changed_value1'
但是我该如何使用循环来改变嵌套键的值呢?
换句话说,我想生成以下命令:
example_dict['key1'] = 'changed_value1'
example_dict['key2'] ['key2a] = 'changed_value2a'
example_dict['key3'] ['key3a] ['key3aa'] = 'changed_value3aa'
example_dict['key3'] ['key3a] ['key3ab'] = 'changed_value3ab'
example_dict['key3'] ['key3a] ['key3ac'] = 'changed_value3ac'
example_dict['key3'] ['key3b] = 'changed_value3b1', 'changed_value3b2'
2 个回答
0
这样怎么样呢?当然,你需要根据自己的需求来修改一下 modifier
;下面的代码输出是:
{'key1': 'value1',
'key2': {'key2a': 'value2a'},
'key3': {'key3a': {'key3aa': 'value3aa modified',
'key3ab': 'value3ab modified',
'key3ac': 'value3ac modified'},
'key3b': ['value3b1 modified', 'value3b2 modified']}}
def modify_recursively_in_place(d, modifier, path=()):
for k, v in d.items():
if isinstance(v, dict):
modify_recursively_in_place(v, modifier, (*path, k))
elif isinstance(v, list):
for i, e in enumerate(v):
if isinstance(e, (dict, list)):
modify_recursively_in_place(e, modifier, (*path, k, i))
else:
v[i] = modifier(v[i], (*path, k, i))
else:
d[k] = modifier(v, (*path, k))
# ---
def modifier(value, path):
if isinstance(path[-1], str) and path[-1].startswith("key3a"):
value = f"{value} modified"
if isinstance(path[-1], int):
value = f"{value} modified"
return value
example_dict = {
"key1": "value1",
"key2": {
"key2a": "value2a",
},
"key3": {
"key3a": {
"key3aa": "value3aa",
"key3ab": "value3ab",
"key3ac": "value3ac",
},
"key3b": [
"value3b1",
"value3b2",
],
},
}
modify_recursively_in_place(example_dict, modifier)
print(example_dict)
0
除了键和值对,还要返回父级。
def recursive(src, so_far=()):
if isinstance(src, dict):
for key, value in src.items():
if isinstance(value, dict) or isinstance(value, list):
yield from recursive(value, so_far + (key,))
else:
yield src, key, value
elif isinstance(src, list):
for index, value in enumerate(src):
if isinstance(value, dict) or isinstance(value, list):
yield from recursive(value, so_far + (index,))
else:
yield src, index, value
else:
raise ValueError
for parent, key, value in recursive(example_dict):
parent[key] = "modified " + value