我有一本这样的字典:
{'A': [12343,
2342349,
{'B': [3423,
342349283,
73,
{'C': [-23,
-2342342,
36],
'D': [-2,
-2520206,
63]}],
'E': [-1.5119711426000446,
-1405627.5262916991,
26.110728689275614,
{'F': [-1.7211282679440503,
-1601770.8149339128,
113.9541439658396],
'G': [0.21282003105839883,
196143.28864221353,
-13.954143965839597,
{'H': [0.43384581412426826,
399408,
203],
'I': [-0.22,
-203265,
-103]}]}]}]}
我想要一个可以获取值的函数。
例如traverse(dictionary,'F')
,它应该给我输出。找不到任何解决方案。我能够遍历1或2个级别,但不能更多。代码要么会中断,要么不会停止。
我当前无法使用的解决方案是:
def traverse(dictionary,search):
print "Traversing"
if isinstance(dictionary,dict):
keys = dictionary.keys()
print keys
if search in keys:
print "Found",search,"in",keys
print "Printing found dict",dictionary
print
print "Check this out",dictionary.get(search)
print "Trying to return"
val=dictionary.get(search)
return val
else:
for key in keys:
print 'Key >>>>>>>>>',dictionary.get(key)
print
temp=dictionary.get(key)[-1]
print "Temp >>>>>>>",temp
traverse(temp,search)
答案 0 :(得分:1)
您需要同时处理字典和列表,才能完全遍历您的结构。您目前仅处理字典,但是其中带有'F'
键的字典是列表对象的元素,因此您无法使用方法找到它。
虽然您可以使用递归来利用函数调用堆栈来跟踪结构的不同级别,但我还是要反复进行并使用列表或collections.deque()
(更快这项工作)来跟踪仍要处理的对象。这样效率更高,并且不会遇到较大结构的递归深度错误。
例如,使用生成器函数遍历所有元素,然后产生每个访问的元素,可能是:
from collections import deque
def walk(d):
queue = deque([d])
while queue:
elem = queue.popleft()
if isinstance(elem, dict):
queue.extend(elem.values())
elif isinstance(elem, list):
queue.extend(elem)
yield elem
以上使用队列先处理元素呼吸;要将其用作堆栈,只需将queue.popleft()
替换为queue.pop()
。
然后您可以使用上面的助行器找到您的元素:
def search_key(obj, key):
for elem in walk(obj):
if isinstance(elem, dict) and key in elem:
return elem
对于您的字典,上面的代码返回包含查找键的第一个字典:
>>> search_key(dictionary, 'F')
{'F': [-1.7211282679440503, -1601770.8149339128, 113.9541439658396], 'G': [0.21282003105839883, 196143.28864221353, -13.954143965839597, {'H': [0.43384581412426826, 399408, 203], 'I': [-0.22, -203265, -103]}]}
>>> _['F']
[-1.7211282679440503, -1601770.8149339128, 113.9541439658396]
如果您只对给定键的值感兴趣,请当然将其返回:
def search_key(obj, key):
for elem in walk(obj):
if isinstance(elem, dict) and key in elem:
return elem[key]
答案 1 :(得分:1)
假设在任何给定的数据结构中只有一个匹配的键,则可以使用一个函数来递归地遍历字典以查找键并返回其值(如果找到),如果找不到,则会引发异常,以便调用框架可以捕获它并移至下一个候选键:
def traverse(dictionary, search):
for k, v in dictionary.items():
if k == search:
return v
if isinstance(v[-1], dict):
try:
return traverse(v[-1], search)
except ValueError:
pass
raise ValueError("Key '%s' not found" % search)
以便traverse(d, 'F')
返回(假设您的字典存储为变量d
):
[-1.7211282679440503, -1601770.8149339128, 113.9541439658396]
另一方面,如果给定数据中可以有多个匹配项,则可以使函数产生匹配键的值,从而使该函数成为生成器,生成0到许多匹配键的子列表:
def traverse(dictionary, search):
for k, v in dictionary.items():
if k == search:
yield v
if isinstance(v[-1], dict):
yield from traverse(v[-1], search)
使list(traverse(d, 'F'))
返回:
[[-1.7211282679440503, -1601770.8149339128, 113.9541439658396]]