我在stackoverflow上进行了搜索,发现以下代码使我可以递归地在嵌套字典中搜索键值。但是,我也想跟踪外部dict的键值。我该怎么办?
从下面链接中Alfe的答案中,我可以使用下面的代码获取嵌套字典中键的所有值。 Find all occurrences of a key in nested python dictionaries and listsdata = {'item1': {
'name': 'dummy',
'type': 'dummy1'},
'item2': {
'name': 'dummy',
'type': 'dummy1',
'label':'label2'
},
'item3': {
'name': 'dummy',
'type': 'dummy1',
'label':'label3'},
'item4': {
'name': 'dummy',
'type': 'dummy1'}
}
def find(key, dictionary):
for k, v in dictionary.items():
if k == key:
yield v
elif isinstance(v, dict):
for result in find(key, v):
yield result
elif isinstance(v, list):
for d in v:
for result in find(key, d):
yield result
In[1]:list(find('label', data))
Out[1]:
['label2', 'label3']
但是,我还需要记录以下外部dict键。我应该怎么做?另外,我的数据可能具有多个层次。
{'item2':'label2',
'item3':'label3'
}
我还发现此链接中的recursive_lookup编写得很整齐。但是,当我尝试运行它时,它会返回None
。
Find keys in nested dictionary
def recursive_lookup(k, d):
if k in d:
return d[k]
for v in d.values():
if isinstance(v, dict):
return recursive_lookup(k, v)
return None
当我打电话给None
时,它将返回recursive_lookup('label', data)
。
如果有人可以为我指出上面的代码为什么不起作用,那也很好!
答案 0 :(得分:1)
无论嵌套的深度有多深(无论如何都达到堆栈限制),此方法都应该起作用。跟踪dict的键的请求有点尴尬-我用一个元组返回了该对。请注意,如果找到的值位于最外面的字典中,则不会采用元组格式。
def recursive_lookup(key, d):
if key in d:
return d[key]
for k, v in d.items():
if isinstance(v, dict):
result = recursive_lookup(key, v)
if result:
return k, result
print(recursive_lookup('label', data))
输出:
('item2', 'label2')
这是一个有点混乱的版本(我对内部函数并不感到疯狂,但至少累加器列表不是参数,也不是全局的),但会返回嵌套到的所有已找到项目的列表堆栈限制,最外面的键除外:
def recursive_lookup(key, d):
def _lookup(key, d):
if key in d:
return d[key]
for k, v in d.items():
if isinstance(v, dict):
result = _lookup(key, v)
if result:
accumulator.append((k, result))
accumulator = []
_lookup(key, d)
return accumulator
输出:
[('item3', 'label3'), ('item2', 'label2')]
如果要输出字典,可以很容易地对其进行修改-将accumulator = []
替换为accumulator = {}
,而将accumulator.append((k, result))
替换为accumulator[k] = result
,但这可能很难处理,并且您不能存储重复的键条目。
关于您的最后一个问题,您得到None
的原因是因为检查第一项是否找到东西后,内部循环returns
。由于label
位于items()
数组的第二个位置,因此永远不会被查看。
答案 1 :(得分:1)
函数返回路径和值以及元组列表。
def dict_key_lookup(_dict, key, path=[]):
results = []
if isinstance(_dict, dict):
if key in _dict:
results.append((path+[key], _dict[key]))
else:
for k, v in _dict.items():
results.extend(dict_key_lookup(v, key, path= path+[k]))
elif isinstance(_dict, list):
for index, item in enumerate(_dict):
results.extend(dict_key_lookup(item, key, path= path+[index]))
return results
希望这会有所帮助。
答案 2 :(得分:0)
首先创建一个列表,例如
outerKeyList = []
然后,每当您要存储密钥时(例如在返回要搜索的项目之前),只需运行
outerKeyList.append(key).
这将为您提供递归功能之外所有键的便捷列表。
答案 3 :(得分:0)
如果您的dict
中只有一个嵌套的dict
,则可以使用dict
理解:
In [9]: def find(label, data):
...: return {outer_key: inner_val for outer_key, outer_val in data.items() for inner_key, inner_val in outer_val.items() if inner_key == label}
...:
In [10]: find('label', data)
Out[10]: {'item2': 'label2', 'item3': 'label3'}