python中集合相等的异常行为

2024-03-29 15:21:14 发布

您现在位置:Python中文网/ 问答频道 /正文

当我运行这行代码时,我不明白为什么从同一个列表创建的listssets是相等的

class Field(object):
    def __init__(self, fieldnames):
        self.name = fieldnames[0]
        self.alias = frozenset(fieldnames)

    def __eq__(self, other):
        if not isinstance(other, Field):
            return False
        return len(self.alias & other.alias) >= 1

    def __hash__(self):
        return hash(self.name)

    def __str__(self):
        return "{field_name: %s}" % self.name

    def __repr__(self):
        return "<Field: (%s: %r)" %(self.name, self.alias)

In [185]: field_list1 = [["Field 1"], ["Field 2"], ["Field 3"]]

In [186]: field_list2 = [["Field 1"], ["Field 21", "Field 2"], ["Field 3"]]

In [187]: field1 = [Field(f) for f in field_list1]

In [188]: field2 = [Field(f) for f in field_list2]

In [189]: field1 == field2
Out[189]: True

In [190]: set(field1) == set(field2)
Out[190]: False

根据python文档,如果第一个集合的每个元素都在第二个集合中,那么两个集合是相等的,反之亦然。根据这个定义,两个集合应该相等,但我不知道为什么它们不相等。你知道吗

Therefore I wanted to know reason behind such behavior?


Tags: nameinselffalsefieldreturndefalias
2条回答

field1 == field2使用==运算符执行逐项比较(通过调用__eq__)。你知道吗

set(field1) == set(field2)检查是否所有元素都在这两个集合中。集合中的元素由它们的散列来标识。你可以根据名字计算哈希值。列表中的某些元素具有不同的名称,因此它们是不同的集合元素。你知道吗

print(field1[1].name)  # 'Field 2'
print(field2[1].name)  # 'Field 21'

总之,列表比较基于__eq__,而集合比较基于__hash__。它们基于Field类中完全不同的计算,因此得到不同的结果。你知道吗

你们有不同的比较。你知道吗

在比较两个列表时,第一个列表中的每个元素通过==与另一个列表中的等效元素进行比较,该方法调用eq方法。尽管您的方法代码非常奇怪(为什么不只是len(self.alias) == len(other.alias)?),根据别名属性的相对大小,它会导致True或False。你知道吗

但是,设置的工作方式完全不同。比较是通过哈希而不是相等来完成的;并且您已经定义了__hash__方法,以便根据名称而不是别名返回不同的结果。你知道吗

相关问题 更多 >