使用点符号string检查字典
这个正在吹我的脑海。 鉴于以下字典:
d = {"a":{"b":{"c":"winning!"}}}
我有这个string(从外部来源,我不能改变这个比喻)。
k = "abc"
我需要确定字典是否有 'c' 键 ,所以如果没有的话可以添加它。
这适用于检索一个点符号值:
reduce(dict.get, key.split("."), d)
但我不知道如何“减less”has_key检查或类似的东西。
我的最终问题是:给定“abcde”,我需要创build字典中所有必要的元素 ,但是如果它们已经存在的话,不要跺脚。 如果有人知道如何做到这一切,你将成为我的英雄。
…或使用recursion:
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]
你可以使用一个无限的,嵌套的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'
鉴于你的虚线string,这是你可以做的:
>>> import operator >>> keys = "abc".split(".") >>> lastplace = reduce(operator.getitem, keys[:-1], d) >>> lastplace.has_key(keys[-1]) False
你可以设置一个值:
>>> lastplace[keys[-1]] = "something" >>> reduce(operator.getitem, keys, d) 'something' >>> d['a']['b']['c'] 'something'
如何迭代的方法?
def create_keys(d, keys): for k in keys.split("."): if not k in d: d[k] = {} #if the key isn't there yet add it to d d = d[k] #go one level down and repeat
如果您需要最后一个键值映射到字典以外的任何东西,您可以将该值作为附加parameter passing,并在循环之后设置:
def create_keys(d, keys, value): keys = keys.split(".") for k in keys[:-1]: if not k in d: d[k] = {} d = d[k] d[keys[-1]] = value
d = {"a":{}} k = "abc".split(".") def f(d, i): if i >= len(k): return "winning!" c = k[i] d[c] = f(d.get(c, {}), i + 1) return d print f(d, 0) "{'a': {'b': {'c': 'winning!'}}}"