使用点符号字符串"abcde"检查嵌套字典会自动创建缺少的级别

hik*_*aru 12 python dictionary nested defaultdict

这个让我大吃一惊.鉴于以下字典:

    d = {"a":{"b":{"c":"winning!"}}}
Run Code Online (Sandbox Code Playgroud)

我有这个字符串(来自外部来源,我不能改变这个比喻).

    k = "a.b.c"
Run Code Online (Sandbox Code Playgroud)

我需要确定字典是否有密钥 'c',所以如果没有,我可以添加它.

这可以游戏地检索点符号值:

    reduce(dict.get, key.split("."), d)
Run Code Online (Sandbox Code Playgroud)

但我无法弄清楚如何'减少'has_key检查或类似的东西.

我的最终问题是:给定"abcde",我需要创建字典中所需的所有元素,但如果它们已经存在则不要踩它们.如果有人知道做出这一切的真正方式,那么你将成为我的英雄.

jte*_*ace 22

您可以使用无限的嵌套defaultdict:

>>> from collections import defaultdict
>>> infinitedict = lambda: defaultdict(infinitedict)
>>> d = infinitedict()
>>> d['key1']['key2']['key3']['key4']['key5'] = 'test'
>>> d['key1']['key2']['key3']['key4']['key5']
'test'
Run Code Online (Sandbox Code Playgroud)

鉴于你的虚线,这是你可以做的:

>>> import operator
>>> keys = "a.b.c".split(".")
>>> lastplace = reduce(operator.getitem, keys[:-1], d)
>>> lastplace.has_key(keys[-1])
False
Run Code Online (Sandbox Code Playgroud)

您可以设置一个值:

>>> lastplace[keys[-1]] = "something"
>>> reduce(operator.getitem, keys, d)
'something'
>>> d['a']['b']['c']
'something'
Run Code Online (Sandbox Code Playgroud)

  • 这很深.`infinitedict = lambda:defaultdict(infinitedict)`+ 1 (7认同)

tob*_*s_k 11

...或使用递归:

def put(d, keys, item):
    if "." in keys:
        key, rest = keys.split(".", 1)
        if key not in d:
            d[key] = {}
        put(d[key], rest, item)
    else:
        d[keys] = item

def get(d, keys):
    if "." in keys:
        key, rest = keys.split(".", 1)
        return get(d[key], rest)
    else:
        return d[keys]
Run Code Online (Sandbox Code Playgroud)