Python中的IdentitySet?
我需要一个使用set(is)比较add()的集合,而不是值(==)比较.
例如,我已经定义了一个挂起__eq__和__hash__的Point类(带有不可变的x / y).点正确地比较自己,并且具有相同x / y值的Point的两个实例回答True到==并且False为.我需要在我的集合中添加两个这样的实例,重要的是结果包含两个实例,即使它们的x / y值相同.一些Smalltalks为此目的定义了IdentitySet. 我想知道,例如,我是否可以修补内置的set类以包含identityAdd和identityRemove方法.这可能会奏效,但它似乎是一个黑客. 有没有更好的办法? 解决方法
这是基于id – >的实现.对象图(由
@nmclean建议)和
collections.MutableSet :
from collections import MutableSet class IdentitySet(MutableSet): key = id # should return a hashable object def __init__(self,iterable=()): self.map = {} # id -> object self |= iterable # add elements from iterable to the set (union) def __len__(self): # Sized return len(self.map) def __iter__(self): # Iterable return self.map.itervalues() def __contains__(self,x): # Container return self.key(x) in self.map def add(self,value): # MutableSet """Add an element.""" self.map[self.key(value)] = value def discard(self,value): # MutableSet """Remove an element. Do not raise an exception if absent.""" self.map.pop(self.key(value),None) def __repr__(self): if not self: return '%s()' % (self.__class__.__name__,) return '%s(%r)' % (self.__class__.__name__,list(self)) 例: a = (1,2) print IdentitySet([a,(1,2),a]) # -> IdentitySet([(1,2)]) # only one instance of `a` print s != Set([a,a]) # it might be unequal because new literal # tuple (1,2) might have a different id print s | Set([a,2)]) # `a` plus two tuples from literals MutableSet自动提供了一些方法:清除,流行,删除,__ior__,__iand__,__ixor__,__isub__,__le__,__lt__,__eq__,__ne__,__gt__,__ge__,__and__,__or__,__sub__,__xor__和isdisjoint. 这里,与基于集合的实现不同,复合操作总是使用重写的基本方法,| (self .__或__(),union)是根据self.add()实现的,因此它为IdentitySet语义提供了正确的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |