如果键在列表中,如何更新嵌套字典中的值? [英] How to update values in nested dictionary if keys are in a list?

查看:55
本文介绍了如果键在列表中,如何更新嵌套字典中的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个钥匙清单

key_lst = ["key1", "key2", "key3"]

我有一个价值

value = "my_value"

以及具有此结构的示例dict my_dict

and an example dict my_dict with this structure

{
"key1": {
    "key2": {
        "key3": "some_value"
        }
    },
}

如何通过遍历/遍历key_lst来动态地将变量value中的新值分配给my_dict["key1"]["key2"]["key3"]?

How can I dynamically assign the new value in variable value to my_dict["key1"]["key2"]["key3"] by going thru / looping over my key_lst?

我不能只说my_dict["key1"]["key2"]["key3"] = value,因为键和键的数量正在变化.我总是在列表中获取键(我必须将值保存到的路径)...

I can not just say my_dict["key1"]["key2"]["key3"] = value since the keys and the number of keys is changing. I always get the keys (the path that i have to save the value at) in a list...

我正在寻找的输出是{'key1': {'key2': {'key3': 'my_value'}}}.字典结构是预定义的.

The output I am looking for is {'key1': {'key2': {'key3': 'my_value'}}}. The dictionary structure is predefined.

我正在使用Python 3.7

I'm using Python 3.7

推荐答案

预定义的字典结构: functools.reduce

您可以使用functools.reduce定义一个函数来重复应用getitem,然后设置一个提供的值:

Predefined dictionary structure: functools.reduce

You can define a function using functools.reduce to apply getitem repeatedly and then set a supplied value:

from functools import reduce
from operator import getitem

def set_nested_item(dataDict, mapList, val):
    """Set item in nested dictionary"""
    reduce(getitem, mapList[:-1], dataDict)[mapList[-1]] = val
    return dataDict

key_lst = ["key1", "key2", "key3"]
value = "my_value"
d = {"key1": {"key2": {"key3": "some_value"}}}

d = set_nested_item(d, key_lst, value)

print(d)
# {'key1': {'key2': {'key3': 'my_value'}}}

注意operator.getitem用于访问dict.__getitem__或其更常用的语法糖dict[].在这种情况下,functools.reducedataDict上递归调用getitem,依次使用mapList[:-1]中的每个值作为参数.对于[:-1],我们有意省略了最后一个值,因此我们可以通过dict[key] = value__setitem__用作最终键.

Note operator.getitem is used to access dict.__getitem__, or its more commonly used syntactic sugar dict[]. In this instance, functools.reduce calls getitem recursively on dataDict, successively using each value in mapList[:-1] as an argument. With [:-1], we intentionally leave out the last value, so we can use __setitem__ via dict[key] = value for the final key.

如果希望在尚未定义的任意分支处添加项目,则可以构造defaultdict.为此,您可以先 defaultify 您的常规词典输入,然后像以前一样使用set_nested_item:

If you wish to add items at arbitrary branches not yet been defined, you can construct a defaultdict. For this, you can first defaultify your regular dictionary input, then use set_nested_item as before:

from collections import defaultdict

def dd_rec():
    return defaultdict(dd_rec)

def defaultify(d):
    if not isinstance(d, dict):
        return d
    return defaultdict(dd_rec, {k: defaultify(v) for k, v in d.items()})

dd = defaultify(d)

key_lst = ["key1", "key2", "key5", "key6"]
value = "my_value2"
dd = set_nested_item(dd, key_lst, value)

print(dd)

# defaultdict(<function __main__.<lambda>>,
#             {'key1': defaultdict(<function __main__.<lambda>>,
#                          {'key2': defaultdict(<function __main__.<lambda>>,
#                                       {'key3': 'my_value',
#                                        'key5': defaultdict(<function __main__.<lambda>>,
#                                                    {'key6': 'my_value2'})})})})

这篇关于如果键在列表中,如何更新嵌套字典中的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆