Python 如何从容器中移除相等的对象(但不一定是相同的对象)?
我想做一些类似的事情:Python 如何从容器中移除相等的对象(但不一定是相同的对象)?,python,object,set,containers,Python,Object,Set,Containers,我想做一些类似的事情: class Thing(object): self.mySet = Set() self.mySet.add(Cell((0,0),25)) self.mySet.add(Cell((0,1),50)) self.mySet.add(Cell((0,2),75)) def ClaimCell(self, cell): self.mySet.remove(cell) class Cell(object):
class Thing(object):
self.mySet = Set()
self.mySet.add(Cell((0,0),25))
self.mySet.add(Cell((0,1),50))
self.mySet.add(Cell((0,2),75))
def ClaimCell(self, cell):
self.mySet.remove(cell)
class Cell(object):
def __init__(self,index,value):
self.index = index
self.value = value
但本质上,我希望能够基于
单元格的成员而不是实例本身进行查找。我希望能够测试传入的cell.index
是否与self.mySet
中的任何cell.index
匹配。是否有我可以为此重写的\uuu cmp\uuu
类型方法?或者我被迫循环遍历集合,每次检查索引,然后手动删除相应的条目?在Python中,两个相似的对象并不相同。引用
如果类没有定义\uuuu cmp\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;如果它定义了\uu cmp\uu()
或\uu eq\uuu()
而不是\uuu hash\uuu()
,则其实例将无法在哈希集合中使用。如果类定义了可变对象并实现了\uuu cmp\uuu()
或\uuu eq\uuuu()
方法,那么它不应该实现\uu hash\uuuu()
,因为可哈希集合实现要求对象的哈希值是不可变的(如果对象的哈希值发生变化,它将位于错误的哈希桶中)
默认情况下,用户定义的类具有\uuu cmp\uu()
和\uu hash\uuu()
方法;使用它们,所有对象比较不相等(除了它们自己)和x.\uuuu hash\uuuu()
返回从id(x)
派生的结果
因此,如果您想将两个对象视为相同的对象,则需要重写\uuuuueq\uuuu
和\uuuuuuuhash\uuuu
方法,如下所示
class Cell(object):
def __init__(self, index, value):
self.index = index
self.value = value
def __hash__(self):
return hash(self.index)
def __eq__(self, other):
return other.index == self.index
def __repr__(self):
return "Index: {}, Value: {}".format(self.index, self.value)
class Thing(object):
def __init__(self):
self.mySet = set()
self.mySet.add(Cell((0, 0), 25))
self.mySet.add(Cell((0, 1), 50))
self.mySet.add(Cell((0, 2), 75))
def ClaimCell(self, cell):
self.mySet.remove(cell)
print(self.mySet)
Thing().ClaimCell(Cell((0, 1), 99))
由于您希望基于索引
进行比较,因此只有索引
会被散列并在重写的\uuuuuuuuuuuuu散列
方法中返回
如果两个散列值相等,Python将通过内部调用\uuuuueq\uuu
方法来检查这两个对象是否相同。因此,我们也重写了该方法,只返回比较两个对象的index
的结果
def __eq__(self, other):
return other.index == self.index
我们已经覆盖了\uuu repr\uu
,只是为了在打印时查看实际的元素
现在,当你这样做的时候
class Cell(object):
def __init__(self, index, value):
self.index = index
self.value = value
def __hash__(self):
return hash(self.index)
def __eq__(self, other):
return other.index == self.index
def __repr__(self):
return "Index: {}, Value: {}".format(self.index, self.value)
class Thing(object):
def __init__(self):
self.mySet = set()
self.mySet.add(Cell((0, 0), 25))
self.mySet.add(Cell((0, 1), 50))
self.mySet.add(Cell((0, 2), 75))
def ClaimCell(self, cell):
self.mySet.remove(cell)
print(self.mySet)
Thing().ClaimCell(Cell((0, 1), 99))
你会得到
set([Index: (0, 0), Value: 25, Index: (0, 2), Value: 75])
注意,我们试图删除的<代码>单元< /代码>对象的值为<代码> 99 >代码>,因为我们只考虑了“代码>索引/代码>对象标识,它用索引<代码>(0, 1)< /C> >删除<代码>单元< /代码> .< /p>该CaseS的集合是什么?您尝试重写<代码>(在Cell类上)@user2357112--hm,这正是我在@MrDuk上发现的:正如页面顶部所说,该模块已被弃用
set
(带小写s)现在是一种内置类型。也许您可以使用字典{cell.index:cell}
而不是集合。