通过键列表访问嵌套的字典项? [英] Access nested dictionary items via a list of keys?

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

问题描述

我有一个复杂的字典结构,我想通过键列表访问它以寻址正确的项目.

dataDict = {一种":{"r": 1,"s": 2,t":3},乙":{你":1,v":{x":1,"y": 2,z":3},w":3}}maplist = ["a", "r"]

maplist = ["b", "v", "y"]

我已经编写了以下代码,但如果有人有想法,我相信有更好、更有效的方法来做到这一点.

# 从字典中获取给定数据,位置以列表形式提供def getFromDict(dataDict, mapList):对于 mapList 中的 k:dataDict = dataDict[k]返回数据字典# 在字典中设置给定数据,并以列表形式提供位置def setInDict(dataDict, mapList, value):对于 mapList[:-1] 中的 k:dataDict = dataDict[k]dataDict[mapList[-1]] = 值

解决方案

使用reduce()遍历字典:

from functools import reduce # Python 3 的向前兼容性进口经营者def getFromDict(dataDict, mapList):返回减少(operator.getitem,mapList,dataDict)

并重用 getFromDict 来查找存储 setInDict() 值的位置:

def setInDict(dataDict, mapList, value):getFromDict(dataDict, mapList[:-1])[mapList[-1]] = value

mapList 中除最后一个元素外的所有元素都需要找到父"字典来添加值,然后使用最后一个元素将值设置为正确的键.

演示:

<预><代码>>>>getFromDict(dataDict, [a", r"])1>>>getFromDict(dataDict, [b", v", y"])2>>>setInDict(dataDict, [b", v", w"], 4)>>>导入打印>>>pprint.pprint(dataDict){'a': {'r': 1, 's': 2, 't': 3},'b': {'u': 1, 'v': {'w': 4, 'x': 1, 'y': 2, 'z': 3}, 'w': 3}}

请注意 Python PEP8 样式指南 规定了 snake_case函数名称.以上对于列表或字典和列表的混合同样适用,因此名称应该是 get_by_path()set_by_path():

from functools import reduce # Python 3 的向前兼容性进口经营者def get_by_path(root, items):"按项目序列访问根中的嵌套对象.""返回减少(operator.getitem,项目,根)def set_by_path(root, items, value):"按项目序列在根中的嵌套对象中设置值."";get_by_path(root, items[:-1])[items[-1]] = value

为了完成起见,一个删除键的函数:

def del_by_path(root, items):"按项目序列删除根中嵌套对象中的键值."del get_by_path(root, items[:-1])[items[-1]]

I have a complex dictionary structure which I would like to access via a list of keys to address the correct item.

dataDict = {
    "a":{
        "r": 1,
        "s": 2,
        "t": 3
        },
    "b":{
        "u": 1,
        "v": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "w": 3
        }
}    

maplist = ["a", "r"]

or

maplist = ["b", "v", "y"]

I have made the following code which works but I'm sure there is a better and more efficient way to do this if anyone has an idea.

# Get a given data from a dictionary with position provided as a list
def getFromDict(dataDict, mapList):    
    for k in mapList: dataDict = dataDict[k]
    return dataDict

# Set a given data in a dictionary with position provided as a list
def setInDict(dataDict, mapList, value): 
    for k in mapList[:-1]: dataDict = dataDict[k]
    dataDict[mapList[-1]] = value

解决方案

Use reduce() to traverse the dictionary:

from functools import reduce  # forward compatibility for Python 3
import operator

def getFromDict(dataDict, mapList):
    return reduce(operator.getitem, mapList, dataDict)

and reuse getFromDict to find the location to store the value for setInDict():

def setInDict(dataDict, mapList, value):
    getFromDict(dataDict, mapList[:-1])[mapList[-1]] = value

All but the last element in mapList is needed to find the 'parent' dictionary to add the value to, then use the last element to set the value to the right key.

Demo:

>>> getFromDict(dataDict, ["a", "r"])
1
>>> getFromDict(dataDict, ["b", "v", "y"])
2
>>> setInDict(dataDict, ["b", "v", "w"], 4)
>>> import pprint
>>> pprint.pprint(dataDict)
{'a': {'r': 1, 's': 2, 't': 3},
 'b': {'u': 1, 'v': {'w': 4, 'x': 1, 'y': 2, 'z': 3}, 'w': 3}}

Note that the Python PEP8 style guide prescribes snake_case names for functions. The above works equally well for lists or a mix of dictionaries and lists, so the names should really be get_by_path() and set_by_path():

from functools import reduce  # forward compatibility for Python 3
import operator

def get_by_path(root, items):
    """Access a nested object in root by item sequence."""
    return reduce(operator.getitem, items, root)

def set_by_path(root, items, value):
    """Set a value in a nested object in root by item sequence."""
    get_by_path(root, items[:-1])[items[-1]] = value

And for completion's sake, a function to delete a key:

def del_by_path(root, items):
    """Delete a key-value in a nested object in root by item sequence."""
    del get_by_path(root, items[:-1])[items[-1]]

这篇关于通过键列表访问嵌套的字典项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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