如何更改嵌套键的值

问题描述 投票:0回答:2

目标:我正在尝试更改嵌套字典的值我事先不知道字典的确切结构

这是一个示例输入字典:

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'
python python-3.x dictionary
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
© www.soinside.com 2019 - 2024. All rights reserved.