Python:在嵌套字典中查找值的递归函数不断返回 'None'
Python: recursive function to find value in nested dictionary keeps returning 'None'
我有一个包含显微镜采集元数据的嵌套字典,如下所示:
metadata_dict = {Metadata: {"_text" : "\n\n ",
"Core" : [{"_text" : \n\n ",
"Guid" : [{"_text" : "c..."}],
"UserID" : [{"_text" : "xyz"}]
"AppSW" : [{"_text" : "xT"}]
"AppSWVer" : [{"_text" : "0"}]
}],
"Instrument" : [{"_text" : "\n\n ",
"ContrSWVer : [{"_text": : "10..."}]
...
等等(希望缩进让它不那么混乱)。我只需要某些 key/value 对,我正在使用 python 将值获取到可指定的键。 .get() 方法 returns 'None' 无论参数如何,所以我尝试了以下方法遍历字典中的所有值以查找特定键:
def lookup(dic,prop):
for k, v in dic.items():
if k == prop:
if not isinstance(v, dict):
return v
else:
for key, value in v:
return value
elif isinstance(v, dict):
lookup(v, prop)
调用此方法,e。 G。通过
UserID = lookup(metadata_dict, 'UserID')
print(UserID)
无论参数在字典中的嵌套级别如何,我都只得到 'None' 输出。
This post 似乎解决了同样的问题,但是,在将最后两行更改为
之后
elif isinstance(v, dict):
return lookup(v, prop)
我仍然得到 'None' returns。
这可能是由于递归调用第二个参数为 prop 的方法导致方法 运行 v, prop (和 prop 是一个未定义的变量)而不是从初始函数继承参数(示例中的 'UserID')?如果是这样,考虑到 prop 未定义,为什么 return 不是错误?
你可以试试这个,看看是否有效,如果不行,我建议你解释你想要的结果,你可以以数据为例
def lookup(dic, prop):
res = []
for item in dic.values():
if isinstance(item, list):
for sub_item in item:
for k, v in sub_item.items():
if k == prop:
res.append(v)
elif isinstance(item, dict):
for k, v in item.items():
if k == prop:
res.append(v)
return res
metadata_dict = {"Metadata": {"_text" : "\n\n ",
"Core" : [{"_text" : "\n\n ",
"Guid" : [{"_text" : "c..."}],
"UserID" : [{"_text" : "xyz"}],
"AppSW" : [{"_text" : "xT"}],
"AppSWVer" : [{"_text" : "0"}]
}],
"Instrument" : [{"_text" : "\n\n ",
"Guid" : [{"_text" : "124"}],
"UserID" : [{"_text" : "waefe"}],
"AppSW" : [{"_text" : "asfa"}],
"AppSWVer" : [{"_text" : "21"}]
}]
}}
print(lookup(metadata_dict["Metadata"], "UserID"))
问题是 UserID
在列表 ['Metadata']['Core']
中。
只有当 v
是一个字典时,你才是递归的。
您可以修改代码来处理该问题:
def lookup(dic, prop):
for k, v in dic.items():
if k == prop:
if not isinstance(v, dict):
return v
if isinstance(v, dict):
return lookup(v, prop)
if isinstance(v, list):
for item in v:
found = lookup(item, prop)
if found:
return found
>>> lookup(metadata_dict, "UserID")
[{'_text': 'xyz'}]
我遗漏了:
else:
for key, value in v:
return value
v
是一个字典,所以这应该会引发错误。 return
也将退出该函数 - 因此这只会处理一个值。
如果可以有多个匹配项 - 您可以改用生成器。
def lookup(dic, prop):
for k, v in dic.items():
if k == prop:
if not isinstance(v, dict):
yield v
if isinstance(v, dict):
yield from lookup(v, prop)
if isinstance(v, list):
for item in v:
yield from lookup(item, prop)
输出:
>>> for result in lookup(metadata_dict, "UserID"):
... print(result)
[{'_text': 'xyz'}]
具有多个值的示例:
>>> for result in lookup({"Foo": [{"UserID": 1}], "Bar": {"Baz":[{"Hi": {"UserID": "2"}}]}}, "UserID"):
... print(result)
1
2
我有一个包含显微镜采集元数据的嵌套字典,如下所示:
metadata_dict = {Metadata: {"_text" : "\n\n ",
"Core" : [{"_text" : \n\n ",
"Guid" : [{"_text" : "c..."}],
"UserID" : [{"_text" : "xyz"}]
"AppSW" : [{"_text" : "xT"}]
"AppSWVer" : [{"_text" : "0"}]
}],
"Instrument" : [{"_text" : "\n\n ",
"ContrSWVer : [{"_text": : "10..."}]
...
等等(希望缩进让它不那么混乱)。我只需要某些 key/value 对,我正在使用 python 将值获取到可指定的键。 .get() 方法 returns 'None' 无论参数如何,所以我尝试了以下方法遍历字典中的所有值以查找特定键:
def lookup(dic,prop):
for k, v in dic.items():
if k == prop:
if not isinstance(v, dict):
return v
else:
for key, value in v:
return value
elif isinstance(v, dict):
lookup(v, prop)
调用此方法,e。 G。通过
UserID = lookup(metadata_dict, 'UserID')
print(UserID)
无论参数在字典中的嵌套级别如何,我都只得到 'None' 输出。
This post 似乎解决了同样的问题,但是,在将最后两行更改为
之后 elif isinstance(v, dict):
return lookup(v, prop)
我仍然得到 'None' returns。 这可能是由于递归调用第二个参数为 prop 的方法导致方法 运行 v, prop (和 prop 是一个未定义的变量)而不是从初始函数继承参数(示例中的 'UserID')?如果是这样,考虑到 prop 未定义,为什么 return 不是错误?
你可以试试这个,看看是否有效,如果不行,我建议你解释你想要的结果,你可以以数据为例
def lookup(dic, prop):
res = []
for item in dic.values():
if isinstance(item, list):
for sub_item in item:
for k, v in sub_item.items():
if k == prop:
res.append(v)
elif isinstance(item, dict):
for k, v in item.items():
if k == prop:
res.append(v)
return res
metadata_dict = {"Metadata": {"_text" : "\n\n ",
"Core" : [{"_text" : "\n\n ",
"Guid" : [{"_text" : "c..."}],
"UserID" : [{"_text" : "xyz"}],
"AppSW" : [{"_text" : "xT"}],
"AppSWVer" : [{"_text" : "0"}]
}],
"Instrument" : [{"_text" : "\n\n ",
"Guid" : [{"_text" : "124"}],
"UserID" : [{"_text" : "waefe"}],
"AppSW" : [{"_text" : "asfa"}],
"AppSWVer" : [{"_text" : "21"}]
}]
}}
print(lookup(metadata_dict["Metadata"], "UserID"))
问题是 UserID
在列表 ['Metadata']['Core']
中。
只有当 v
是一个字典时,你才是递归的。
您可以修改代码来处理该问题:
def lookup(dic, prop):
for k, v in dic.items():
if k == prop:
if not isinstance(v, dict):
return v
if isinstance(v, dict):
return lookup(v, prop)
if isinstance(v, list):
for item in v:
found = lookup(item, prop)
if found:
return found
>>> lookup(metadata_dict, "UserID")
[{'_text': 'xyz'}]
我遗漏了:
else:
for key, value in v:
return value
v
是一个字典,所以这应该会引发错误。 return
也将退出该函数 - 因此这只会处理一个值。
如果可以有多个匹配项 - 您可以改用生成器。
def lookup(dic, prop):
for k, v in dic.items():
if k == prop:
if not isinstance(v, dict):
yield v
if isinstance(v, dict):
yield from lookup(v, prop)
if isinstance(v, list):
for item in v:
yield from lookup(item, prop)
输出:
>>> for result in lookup(metadata_dict, "UserID"):
... print(result)
[{'_text': 'xyz'}]
具有多个值的示例:
>>> for result in lookup({"Foo": [{"UserID": 1}], "Bar": {"Baz":[{"Hi": {"UserID": "2"}}]}}, "UserID"):
... print(result)
1
2