python中集合相等的异常行为

python中集合相等的异常行为,python,Python,当我运行这行代码时,我无法理解为什么两个列表是相等的,但是从同一个列表创建的集合不是 class Field(object): def __init__(self, fieldnames): self.name = fieldnames[0] self.alias = frozenset(fieldnames) def __eq__(self, other): if not isinstance(other, Field):

当我运行这行代码时,我无法理解为什么两个
列表
是相等的,但是从同一个列表创建的
集合
不是

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
类字段(对象):
定义初始化(self,字段名):
self.name=字段名[0]
self.alias=frozenset(字段名)
定义(自身、其他):
如果不存在(其他,字段):
返回错误
返回len(self.alias和other.alias)>=1
定义散列(自我):
返回散列(self.name)
定义(自我):
返回“{field_name:%s}”%self.name
定义报告(自我):

return“
field1==field2
使用
=
运算器(通过调用
\uuuueq
)执行逐项比较

set(field1)=set(field2)
检查是否所有元素都在两个集合中。集合中的元素通过其哈希值进行标识。您可以根据名称计算哈希值。列表中的某些元素具有不同的名称,因此它们是不同的集合元素

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

总之,列表比较基于
\uuuu eq\uuuu
,而集合比较基于
\uuuu hash\uuuuu
。它们基于
字段
类中完全不同的计算,因此得到不同的结果。

字段1==field2
使用
=/code>运算符执行逐项比较(通过调用
\uuuu eq\uuu

set(field1)=set(field2)
检查是否所有元素都在两个集合中。集合中的元素通过其哈希值进行标识。您可以根据名称计算哈希值。列表中的某些元素具有不同的名称,因此它们是不同的集合元素

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

总之,列表比较基于
\uuuu eq\uuuu
,而集合比较基于
\uuu hash\uuuu
。它们基于
字段
类中完全不同的计算,因此得到不同的结果。

这里进行的比较不同

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


但是,集合的工作方式完全不同。比较是通过哈希而不是相等来完成的;您已经定义了
\uuuu hash\uuu
方法,根据名称而不是别名返回不同的结果。

您在这里进行了不同的比较

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


但是,集合的工作方式完全不同。比较是通过哈希而不是相等来完成的;您已经定义了
\uuuuhash\uuuuuu
方法,以基于名称而不是别名返回不同的结果。

什么是
d
e
?您的意思是
字段列表1
字段列表2
字段1
“字段1”、“字段2”、“字段3”
作为
字段
对象的
名称
属性。但字段2有
“字段1”、“字段21”、“字段3”“。这是不相同的。如果您想找到一个彼此为别名的字段的传递组,可以考虑使用.@ DANILROROSEMAN正确的D表示FieldList1,E意味着FieldList2。什么是<代码> D < /代码>和<代码> List1和<代码>字段List2?>代码> Field1有<代码> >“字段1”、“字段2”、“字段3”作为
字段
对象的
名称
属性在其中。但字段2具有
字段1”、“字段21”、“字段3“< /代码>。这些不相同。如果您想找到彼此为别名的字段的传递组,则可以考虑使用.@ DayielRoSeMon正确的D表示字段FieldList1,E表示字段FieldList2。