深集python字典

RA.*_*RA. 7 python dictionary python-2.7

我有一个保存的 Python 字典键列表:

['level_one', 'level_two', 'test']

这些是字典的键:

mydict = {
    'level_one' : {
        'level_two' : {
            'test' : "Hello World"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

通常我可以这样设置test键:

mydict['level_one']['level_two']['test'] = "Hello StackOverflow"

不幸的是,列表/字典是即时生成的,我不知道它能走多远。是否有可能在不使用大括号的情况下通过键列表更新 dict 键?

我只能反映这个获取字符串的功能:

def deepGet(sourceDict, *keys):
    return reduce(lambda d, k: d.get(k) if d else None, keys, sourceDict)

> deepGet(mydict, *['level_one', 'level_two', 'test'])
>> Hello World
Run Code Online (Sandbox Code Playgroud)

不是重复的。这是关于设置,而不是获取嵌套字典。

Mah*_*emi 6

现在有一种动态深度设置值的方法,而无需将容器类型更改为 defaultdict 或其他一些动态创建类型:glom.assign()

您的案例的使用示例:

import glom

target = {}
path = 'level_one.level_two.test'

glom.assign(target, path, 'hello world', missing=dict)
# {'level_one': {'level_two': {'test': 'hello world'}}}
Run Code Online (Sandbox Code Playgroud)

请注意,我们通过了missing=dict, 告诉 glom 使用内置的 dict 构造函数创建缺少的键。您还需要pip install glom,但它是纯 Python 并与 Python 2、3 和 PyPy 兼容。

你可以用glom做更多的事情,尤其是在深度获取和设置方面。我应该知道,因为(完全披露)我创建了它。这意味着如果你发现一个缺口,你应该让我知道


Run Code Online (Sandbox Code Playgroud)


Kev*_*vin 5

我们需要一个defaultdict能够一直创建自己的新实例。

import collections

recursive_dict = lambda: collections.defaultdict(recursive_dict)

mydict = recursive_dict()
Run Code Online (Sandbox Code Playgroud)

在这一点上,您可以简化您的deepGet使用,operator.getitem而不是您现在拥有的 lambda。 operator.getitem是 的“简写” lambda a, b: a[b]

至于设置一个键,你可以只写一个循环:

keys = ['level_one', 'level_two', 'test']
d = mydict
for key in keys[:-1]:
    d = d[key]
d[keys[-1]] = 'Hello World'
Run Code Online (Sandbox Code Playgroud)

如果缺少字典,defaultdict 将默默地创建它们,无需先检查它们。

将其转换为reduce()调用留给读者作为练习。