【问题标题】:check if a class instance (which serves as a dict key in this case), has all the same attributes as another instance of the same class检查一个类实例(在这种情况下用作 dict 键)是否具有与同一类的另一个实例相同的属性
【发布时间】:2017-02-25 02:57:27
【问题描述】:

我想创建一个自定义类并使用该类的实例作为字典的键。

然后我想创建该类的其他实例,并检查所有属性是否与我作为该字典的键添加的实例相同。

我认为我在这方面失败了,因为当我尝试使用:

if my_object in my_dict:
    my_dict[my_object]['another_dict_key'].append('Found you!')
else:
    my_dict.update(my_object:{'another_dict_key':[]})

我想它永远不会出现在 if 语句中,因为 my_object 永远不会与已经是 dict 键的“my_object”实例匹配,因为它们不是完全相同的实例——即使它们具有相同的属性——

我在其他帖子中阅读了一些关于此以及 hasheq 的内容,但我仍然感到困惑。我觉得也许有一种简单的方法可以做到这一点,或者我可以完全尝试另一种方法。但是想问问。

这是对代码的更全面的了解,我在上面粘贴的 sn-p 只是为了隔离问题,我想这里是更深入的了解,如果这有帮助,顺便说一句:

master_dict = {}
i = 0
for order in orders:

    normalized_structure = Normalized_Structure(order)
    if normalized_structure in master_dict:
        if 'ORD_INSTRUCTIONS' in master_dict[normalized_structure]:
            master_dict[normalized_structure]['ORD_INSTRUCTIONS'].append(Normalized_Order_Instructions(order))
        else:
            master_dict[normalized_structure]['ORD_INSTRUCTIONS'] = Normalized_Order_Instructions(order)
    else:
        master_dict.update({normalized_structure:{'STRUCTURE_ID':i, 'ORD_INSTRUCTIONS':[]}})
        master_dict[normalized_structure]['ORD_INSTRUCTIONS'].append(Normalized_Order_Instructions())

【问题讨论】:

  • 嗨史蒂文,我看过了,但我不确定如何在不设置哈希/eq 煞费苦心地列出每个属性的情况下做到这一点。对于一个有 20 个属性的类,有没有捷径可以让它更合理?
  • 我猜你可以对哈希做def __eq__(self, other): return all(v == getattr(other, k) for k, v in vars(self).items()) 和类似的东西,看看如何做自定义哈希实现。不过,您可能只需要一些简单的东西。
  • 当您说类似/简单的哈希时,例如,甚至可能像这个答案一样返回 0?有没有像你在上面写的那样光滑的衬里,可以在散列中工作?谢谢-我是新手...stackoverflow.com/questions/4005318/how-to-implement-a-good-hash-function-in-python

标签: python dictionary attributes key instance


【解决方案1】:

我认为通常最好写出并比较每个属性,但是对于 20 个属性,您可能需要更灵活和简单的方法。所以对于平等检查你可以有

def __eq__(self, other):
    return isinstance(other, type(self)) and all(v == getattr(other, k)
                                                 for k, v in vars(self).items())

至于散列,这取决于您要采用哪种方法。

def __hash__(self):
    result = 1
    for k, v in sorted(vars(self).items()):
        result = 31 * result + hash(v) # chosen prime is 31
    return result

或者您可以为每个值创建一个元组并对其进行哈希处理。

def __hash__(self):
    return hash(tuple(v for k, v in sorted(vars(self).items())))

更新:

如果您的某些属性是不可散列的,那么您可以像这样忽略它们。

def __hash__(self):
    return hash(tuple(v for k, v in sorted(vars(self).items())
                      if getattr(v, '__hash__') is not None))

否则采用第一种方法并处理它们如何在循环中散列。

【讨论】:

  • 非常感谢。现在测试。我将不得不跳过 self.items() 中的几个 vars,它们是 dicts,因为它们会抛出不可散列的错误。但我提前知道那些叫什么,我猜可以直接跳过它们。现在测试..
  • 更新了不可散列值的答案。
  • 我必须进行更彻底的测试(也许明天),但现在经过轻度测试,您的解决方案似乎有效,非常感谢您的解释/提供选项。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-07
  • 2021-03-12
  • 2023-01-01
  • 2016-02-13
  • 1970-01-01
  • 2022-06-14
相关资源
最近更新 更多