Python set([]) 如何检查两个对象是不是相等?一个对象需要定义哪些方法来自定义它?
Posted
技术标签:
【中文标题】Python set([]) 如何检查两个对象是不是相等?一个对象需要定义哪些方法来自定义它?【英文标题】:How does a Python set([]) check if two objects are equal? What methods does an object need to define to customise this?Python set([]) 如何检查两个对象是否相等?一个对象需要定义哪些方法来自定义它? 【发布时间】:2011-04-25 22:22:33 【问题描述】:我需要在 Python 中创建一个“容器”对象或类,它会记录我还定义的其他对象。此容器的一个要求是,如果两个对象被认为是相同的,则删除一个(其中一个)。我的第一个想法是使用set([])
作为包含对象,来完成这个要求。
但是,该集合不会删除两个相同的对象实例之一。我必须定义什么来创建一个?
这是 Python 代码。
class Item(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
def __repr__(self):
return "Item(%s, %s)" % (self.foo, self.bar)
def __eq__(self, other):
if isinstance(other, Item):
return ((self.foo == other.foo) and (self.bar == other.bar))
else:
return False
def __ne__(self, other):
return (not self.__eq__(other))
口译员
>>> set([Item(1,2), Item(1,2)])
set([Item(1, 2), Item(1, 2)])
很明显,x == y
调用的__eq__()
不是set调用的方法。什么叫做?我还必须定义什么其他方法?
注意:Item
s 必须保持可变,并且可以更改,因此我无法提供 __hash__()
方法。如果这是唯一的方法,那么我将重写以使用不可变的Item
s。
【问题讨论】:
遇到了同样的问题。我假设您正在处理代码中的少量数据。这可能不是使用数据库的好选择。我记得能够在 C++ 中创建一个集合并定义一个比较器函数,我也相信 Java,但是看起来你不能用 Python 中的字典对象来做到这一点。似乎有人可能已经用 Python 编写了一个可以做到这一点的“集合”库,但我不知道有一个。 【参考方案1】:是的,您需要一个 __hash__()
-method 和您已经提供的比较运算符。
class Item(object):
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
def __repr__(self):
return "Item(%s, %s)" % (self.foo, self.bar)
def __eq__(self, other):
if isinstance(other, Item):
return ((self.foo == other.foo) and (self.bar == other.bar))
else:
return False
def __ne__(self, other):
return (not self.__eq__(other))
def __hash__(self):
return hash(self.__repr__())
【讨论】:
在 Python 3 上,您不需要__ne__
,即使在 2.x 中,您也不应该根据 __eq__
定义 __ne__
。见,***.com/a/30676267/5337834【参考方案2】:
恐怕您必须提供__hash__()
方法。但是你可以这样编码,它不依赖于你的Item
的可变属性。
【讨论】:
docs.python.org/reference/…>这里的第二段指出__hash__()
应该只为不可变对象定义。
@Nathanael:如果对象可能需要更改,您可以制作对象的不可变副本,例如 freezeset() 和 set()。
@Nathanael - 你想怎么打电话给__eq__
?比较那些(1,2)属性?然后,您还必须在 __hash__
方法中返回一些 (1,2) 的哈希值。
或者,既然 foo 和 bar 都是不可变的,那么 __hash__() 可以返回 foo 和 bar 的哈希值之和吗?不... sum 太不可靠了... 如果 foo 是 1 和 bar 2,那将等于 bar 为 1 而 foo 为 2,这是错误的。什么数学函数可以用于此目的?模数或除法应该可以工作。
Nathanael:只需使用 hash
内置函数:hash((self.foo, self.bar))
。这使用元组的散列,这适合您的需要。 (您的__eq__
也可以写成tuple
比较。)以上是关于Python set([]) 如何检查两个对象是不是相等?一个对象需要定义哪些方法来自定义它?的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA 检查 SET 是不是包含对象
如何检查 Python 中是不是同时存在两个变量? [复制]