[英]How do I check value in a nested dictionary in Python?
假設我們有一個字典listD的列表,其中每個字典都嵌套了很多字典。 例如,假設listD的第一個元素是:
listD[0] = {"bar1":{"bar2":{"bar3":1234}}}
現在,我要檢查listD [i] [“ bar1”] [“ bar2”] [“ bar3”] == 1234是否適用於所有i。 對於i = 0的第一個元素,這很容易,因為我們可以使用以下表達式:
listD[0]["bar1"]["bar2"]["bar3"] == 1234
但是我不能簡單地寫一個像這樣的循環:
for dictelem in listD:
if dictelem["bar1"]["bar2"]["bar3"] == 1234:
print "equals 1234"
這是因為listD的某些字典元素可能具有以下形式:
listD[i] = {"bar1":{"bar2":"abcd"}} or
listD[i] = {"bar1":{"bar2":None}}
如果我嘗試訪問不存在的“ bar3”,則會出現錯誤。
現在,我在代碼中手動指定要檢查bar1,bar2和bar3鍵的存在以及它們是否實際上是字典。 但這確實很冗長,我很確定有一種簡單的方法可以做到,但是我不知道怎么做。
def dictcheck(d, p, v):
if len(p):
if isinstance(d,dict) and p[0] in d:
return dictcheck(d[p[0]], p[1:], v)
else:
return d == v
您傳遞一個dict d
,一個鍵p
路徑以及最終值以檢查v
。 它將遞歸地輸入字典,最后檢查最后一個值是否等於v
。
>>> dictcheck({"bar1":{"bar2":{"bar3":1234}}}, ('bar1','bar2','bar3'), 1234)
True
>>> dictcheck({"bar1":1234}, ('bar1','bar2','bar3'), 1234)
False
因此,回答您的問題( 我想檢查listD [i] [“ bar1”] [“ bar2”] [“ bar3”] == 1234是否代表所有i ):
all(dictcheck(x, ('bar1','bar2','bar3'), 1234) for x in listD)
只是這樣使用try/except
塊:
for dictelem in listD:
try:
if dictelem["bar1"]["bar2"]["bar3"] == 1234:
print "equals 1234"
except TypeError:
pass
在處理嵌套字典時,我將它們視為一棵樹,其中的鍵構成了通往值的路徑。 考慮到這一點,我創建了一個非遞歸函數dict_path
, dict_path
帶有一個嵌套字典,鍵路徑和一個值(如果找不到):
def dict_path(dic, path, value_if_not_found=None):
path = path.split('.')
try:
for key in path:
dic = dic[key]
return dic
except (KeyError, TypeError):
return value_if_not_found
listD = [
{"bar1": {"bar2": 'abcd'}},
{"bar1": {"bar2": None}},
{"bar1": {"bar2": {"bar3": 1234}}},
]
for dic in listD:
value = dict_path(dic, 'bar1.bar2.bar3')
if value == 1234:
print 'Equals 1234:', dic
該函數將繼續遍歷嵌套字典,直到出現以下三種情況之一:
KeyError
TypeError
對於情況2和3,我們只返回value_if_not_found
你可以試試這個
for item in listD:
if item.get("bar1",{}).get("bar2",{}).get("bar3","") == 1234:
print "yeah, gotcha"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.