加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

Python中的IdentitySet?

发布时间:2020-12-20 12:22:30 所属栏目:Python 来源:网络整理
导读:我需要一个使用set(is)比较add()的集合,而不是值(==)比较. 例如,我已经定义了一个挂起__eq__和__hash__的Point类(带有不可变的x / y).点正确地比较自己,并且具有相同x / y值的Point的两个实例回答True到==并且False为.我需要在我的集合中添加两个这样的实例,
我需要一个使用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语义提供了正确的.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读