我在这里有一个这样的指导:
example_dict = {
'key1' : 'value1',
'key2' : 'value2',
'key3' :
{
'key3a': 'value3a'
},
'key4' :
{
'key4a':
{
'key4aa': 'value4aa',
'key4ab': 'value4ab',
'key4ac':
{
'key4ac1': [0,1,2],
'key4ac2': (3,4,5),
'key4ac3': [
{
'sub_key_x': 0,
'sub_key_y': 1,
},
6
]
}
},
'key4b': 'value4b'
}
}
我尝试使用此问题的递归代码创建父词典: Get parents keys from nested dictionary
问题是元组或列表,它们打破了循环。 我想在字典中搜索字符串,使用difflib对匹配结果进行排序。
如果有人有想法/架构如何在字典中搜索创建父词典的键/值,那真的很高兴。
例如:
search_in_dict(example_dict, 'sub key')
# returning the content of:
# example_dict['key4']['key4a']['key4ac']['key4ac3']
亲切的问候BaumKuchen
答案 0 :(得分:0)
我不知道你为什么要这样做,当数据结构大小增加时,这种类型的东西会变慢。有一个扁平字典可能会更好,但必须定义扁平化算法。
我为你想要的东西做了一些粗糙的事情。 flatten
方法返回类似于items
((键,值)元组的列表),其中'key'实际上是键的元组。这是必要的,因为字典可能包含相同的键,因此当转换为平面命名空间(需要唯一键)时,就会出现冲突。
class recurdict(dict):
'''
Recursive Dictionary
'''
def __init__(self, idict=None, **kwargs):
dict.__init__(self)
if idict is not None:
self.update(idict)
if len(kwargs):
self.update(kwargs)
def __contains__(self, key):
return (key in self.keys())
def __getitem__(self, key):
if self.__contains__(key):
return self.___getitem__(self, key)
else:
raise KeyError(key)
@staticmethod
def ___getitem__(idict, key):
if dict.__contains__(idict, key):
return dict.__getitem__(idict, key)
else:
result = None
for k, v in idict.iteritems():
if hasattr(v, "keys"):
result = recurdict.___getitem__(v, key)
if(result):
return result
else:
continue
def flatten(self):
return self._flatten(self)
@staticmethod
def _flatten(idict, key_chain = []):
found_keys = []
for k, v in idict.iteritems():
if hasattr(v, "keys"):
found_keys.extend(recurdict._flatten(v, key_chain + [k]))
else:
found_keys.append((tuple(key_chain + [k]), v))
return found_keys
def has_key(self, key):
return self.__contains__(key)
def keys(self):
return self._keys(self)
@staticmethod
def _keys(idict):
found_keys = dict.keys(idict)
for k, v in idict.iteritems():
if hasattr(v, "keys"):
found_keys.extend(recurdict._keys(v))
return found_keys
def update(self, other=None, **kwargs):
if other is None:
pass
elif hasattr(other, "iteritems"):
for k, v in other.iteritems():
self.__setitem__(k,v)
elif hasattr(other, "keys"):
for k in other.keys():
self.__setitem__(k,other.__getitem__(k))
else:
for k, v in other:
self.__setitem__(k,v)
if kwargs:
self.update(kwargs)
example_dict = recurdict\
({
"key1" : "value1",
"key2" : "value2",
"key3" :
{
"key3a": "value3a"
},
"key4" :
{
"key4a":
{
"key4aa": "value4aa",
"key4ab": "value4ab",
"key4ac":
{
"key4ac1": [0,1,2],
"key4ac2": (3,4,5),
"key4ac3":
[
{
"sub_key_x": 0,
"sub_key_y": 1,
},
6
]
}
},
"key4b": "value4b"
}
})
print example_dict.keys()
print "key1" in example_dict
print "key4ac1" in example_dict
print example_dict["key4ac1"]
for (k, v) in example_dict.flatten():
print (k, v)