[英]Traversing Down in a tree like dictionary in Python
我有一本這樣的字典:
{'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)
您需要同時處理字典和列表,才能完全遍歷您的結構。 您目前僅處理字典,但是其中帶有'F'
鍵的字典是列表對象的元素,因此您無法通過方法找到它。
雖然您可以使用遞歸來利用函數調用堆棧來跟蹤結構的不同級別,但我還是要進行迭代,並使用list或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()
。
然后,您可以使用上面的walker查找元素:
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]
假設任何給定的數據結構中只有一個匹配鍵,則可以使用一個函數來遞歸地遍歷字典以查找鍵並返回其值(如果找到),如果找不到,則會引發異常,因此調用框架可以捕獲它並繼續前進到下一個候選鍵:
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]]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.