以这种方式定义哈希对您的应用程序是否有意义确实由您决定,但这似乎不太可能。
无论如何,我可以想到两个选项“与”集合一样快 - O(1) 而不是 O(n) - 它们的速度取决于实现您所描述的哈希函数:
首先,简化您的类并创建实例:
class Item():
def __init__(self, a, b):
self.a = a
self.b = b
def __hash__(self):
return hash(self.a)
def __eq__(self,other):
if isinstance(other, self.__class__):
# Ignoring .b attribute
return self.a == other.a
else:
return NotImplemented
def __repr__(self):
return "Item(%s, %s)" % (self.a, self.b)
i1 = Item(1,2)
i2 = Item(3,4)
i3 = Item(1,5)
print(i1 == i2) # False (.a's don't match)
print(i1 == i3) # True (.a's match)
方法一:字典值
# Using a dict
updating_set = {}
updating_set[i1] = i1 # .values(): [Item(1, 2)]
updating_set[i2] = i2 # .values(): [Item(1, 2), Item(3, 4)]
updating_set[i3] = i3 # .values(): [Item(1, 5), Item(3, 4)]
print(list(updating_set.values()))
# [Item(1, 5), Item(3, 4)]
方法2:使用集合子类
# Using a set subclass
class UpdatingSet(set):
def add(self, item):
if item in self: super().remove(item)
super().add(item)
uset = UpdatingSet()
uset.add(i1) # UpdatingSet({Item(1, 2)})
uset.add(i2) # UpdatingSet({Item(1, 2), Item(3, 4)})
uset.add(i3) # UpdatingSet({Item(1, 5), Item(3, 4)})
奖励方法 3:不需要特殊的哈希函数
class NewItem():
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return "Item(%s, %s)" % (self.a, self.b)
class ItemSet():
def __init__(self):
self.items = {}
def add(self, item):
item_hash = item.a
self.items[item_hash] = item
def values(self):
return self.items.values()
i1 = NewItem(1,2)
i2 = NewItem(3,4)
i3 = NewItem(1,5)
iset = ItemSet()
iset.add(i1) # .values(): [Item(1, 2)]
iset.add(i2) # .values(): [Item(1, 2), Item(3, 4)]
iset.add(i3) # .values(): [Item(1, 5), Item(3, 4)]
print(list(iset.values())) # [Item(1, 5), Item(3, 4)]
第三种方法不需要您实施hash(这可能会导致意想不到的副作用,但模仿内部的哈希过程ItemSet.add()
,使用“哈希函数”作为字典键。
这可能是你最好的选择,除非你really想要实施哈希并了解该决定的影响程度。