如何在Python中检查嵌套字典是否具有特定类型的值?

huangapple go评论57阅读模式
英文:

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)

huangapple
  • 本文由 发表于 2023年8月9日 16:58:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76866114-2.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定