英文:
How do I check if nested dictionary has a value of a specific type in Python?
问题
我想知道如何检查一个包含我的自定义对象的键值对字典,其中值可以是任何Python类型。
假设对象叫做MyObject,我有一个字典如下:
{
"test1": MyObject()
"test2": [MyObject(), MyObject()]
"test3": {"some_key": MyObject()}
"test4": {"some_key": [MyObject()]}
"test5": (MyObject(), MyObject()) # 元组
"test6": {MyObject(), MyObject()} # 集合
"test7": {"some_key1": {"some_key2": {"some_key3": MyObject()}}}
....
}
我想要能够检查这些值中是否有或包含我的自定义对象。这个是否可能?
我已经尝试过以下方法:
def contains_object(d):
for k,v in d.items():
if isinstance(v, MyObject):
return True
elif isinstance(v, (list, set, tuple)):
for i in v:
if isinstance(i, MyObject):
return True
elif isinstance(v, dict):
for a, b in v.items():
if isinstance(b, MyObject):
return True
return False
如何简化上面的解决方案?它应该返回一个布尔值,指示字典是否包含任何值包含MyObject。
英文:
I want to know how I can check if a dictionary with key-value pairs, where the values can be of any python type that contains my custom object.
Lets say object is called MyObject and I have a dictionary.
{
"test1": MyObject()
"test2": [MyObject(), MyObject()]
"test3": {"some_key": MyObject()]
"test4": {"some_key": [MyObject()]
"test5": (MyObject(), MyObject()) # tuple
"test6": {MyObject(), MyObject()} # set
"test7": {"some_key1": {"some_key2": {"some_key3": MyObject()}}}
....
}
I want to be able to check if any of these values are or contain an instance of my custom object. Is this possible?
I Have tried:
def contains_object(d):
for k,v in d.items():
if isinstance(v, MyObject):
return True
elif isinstance(v, (list, set, tuple)):
for i in v:
if isinstance(i, MyObject):
return True
elif isinstance(v, dict):
for a, b in v.items():
if isinstance(b, MyObject):
return True
return False
How do I simplify the above solution. It should return a boolean for whether or not the dictionary has any value that contains MyObject.
答案1
得分: 2
以下是翻译好的部分:
在大多数情况下,这应该有效,或者至少作为进一步扩展的良好起点。它基于评论中建议的简单递归。
def contains_target_type(element, target_type):
if isinstance(element, target_type):
return True
elif isinstance(element, dict):
for value in element.values():
if contains_target_type(value, target_type):
return True
elif isinstance(element, (list, set, tuple)):
for value in element:
if contains_target_type(value, target_type):
return True
return False
您可以这样调用它:
target_type = MyObject
flag = contains_target_type(dict_test_data, target_type)
英文:
Something like this should work in most cases or at least serve as a good starting point for further expansion. It is based on simple recursion as suggested in the comments
def contains_target_type(element, target_type):
if isinstance(element, target_type):
return True
elif isinstance(element, dict):
for value in element.values():
if contains_target_type(value, target_type):
return True
elif isinstance(element, (list, set, tuple)):
for value in element:
if contains_target_type(value, target_type):
return True
return False
You can call it like:
target_type = MyObject
flag = contains_target_type(dict_test_data, target_type)
答案2
得分: 0
需要使用递归方法来遍历你的字典中的任何可能嵌套。以下是相应的代码。它将打印与匹配自定义类的值相关联的键。如果自定义类实例位于可迭代对象中,则相关的键只会报告一次。
class MyObject:
...
_dict = {
"test1": MyObject(),
"test2": [MyObject(), MyObject()],
"test3": {"some_key": MyObject()},
"test4": {"some_key": [MyObject()]},
"test5": (MyObject(), MyObject()),
"test6": {MyObject(), MyObject()},
"test7": {"some_key1": {"some_key2": {"some_key3": MyObject()}}}
}
def parse(d):
key = None
def _parse(d):
nonlocal key
if isinstance(d, MyObject):
print(key)
return True
if isinstance(d, dict):
for key, v in d.items():
_parse(v)
elif isinstance(d, (list, set, tuple)):
for v in d:
if _parse(v) is True:
break
_parse(d)
parse(_dict)
输出结果:
test1
test2
some_key
some_key
test5
test6
some_key3
英文:
You need a recursive approach that allows you to navigate any possible nesting within your dictionary.
The following code will do that. It will print the key that's associated with the value matching the custom class. If the custom class instance is within an iterable, the associated key will only be reported once.
class MyObject:
...
_dict = {
"test1": MyObject(),
"test2": [MyObject(), MyObject()],
"test3": {"some_key": MyObject()},
"test4": {"some_key": [MyObject()]},
"test5": (MyObject(), MyObject()),
"test6": {MyObject(), MyObject()},
"test7": {"some_key1": {"some_key2": {"some_key3": MyObject()}}}
}
def parse(d):
key = None
def _parse(d):
nonlocal key
if isinstance(d, MyObject):
print(key)
return True
if isinstance(d, dict):
for key, v in d.items():
_parse(v)
elif isinstance(d, (list, set, tuple)):
for v in d:
if _parse(v) is True:
break
_parse(d)
parse(_dict)
Output:
test1
test2
some_key
some_key
test5
test6
some_key3
答案3
得分: 0
你可以简化代码如下所示:
def check_for_custom_object(data):
if isinstance(data, MyObject):
# 对MyObject执行某些操作
elif isinstance(data, (list, set, tuple)):
for item in data:
check_for_custom_object(item)
elif isinstance(data, dict):
for value in data.values():
check_for_custom_object(value)
英文:
You can simplify the code such like this:
def check_for_custom_object(data):
if isinstance(data, MyObject):
# do something with MyObject
elif isinstance(data, (list, set, tuple)):
for item in data:
check_for_custom_object(item)
elif isinstance(data, dict):
for value in data.values():
check_for_custom_object(value)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论