Python:创建具有Xorlike行为的集合

2024-05-23 18:37:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个有效实现具有类似XOR行为的集合的用例

一种集合,如果一个元素被添加,从集合中删除该元素(如果该元素已包含在集合中),但如果该元素未包含在集合中,则添加该元素。请参阅以下代码:

# Create set `a`
a = xorset((0,0,0,1,1,2))
assert a == {0,2}
a.add(0)
assert a == {2}
a.add(0)
assert a == {0,2}

a.update((0,0))
assert a == {0,2}
a.update((0,0,0,2,1))
assert a == {1}

到目前为止,我最好的尝试是使用collections计数器对象创建如下集合:

from collections import Counter
def xorset(it):
    return set(k for k,v in Counter(it) if v % 2 == 1)

然后手动执行添加&;更新操作:

import itertools
def xorset_add(s,e):
    if e in s:
         s.remove(e)
    else:
         s.add(e)
    return s # not necessary as works in place
def xorset_update(s,it):
    return set(k for k,v in Counter(itertools.chain(s,it)) if v % 2 == 1)

我想如果有一个lib来处理新元素的添加/删除,可能会有显著的加速,但是我还没有找到任何。有人知道有人存在吗

谢谢


Tags: inimportadd元素forreturnifdef
1条回答
网友
1楼 · 发布于 2024-05-23 18:37:58

除非我误解了你,否则它听起来像是set方法symmetric_difference_update实现了你想要的功能,而且它是一个内置的,它的速度和你想要的一样快

>>> s = set((1,2,3))
>>> s
{1, 2, 3}
>>> s.symmetric_difference_update(set((2,)))         ["add" 2, but removes 2]
>>> s
{1, 3}
>>> s.symmetric_difference_update(set((2,)))         ["add" 2 back]
>>> s
{1, 2, 3}
>>> s.symmetric_difference_update(set((3,4)))        ["add" 3 and 4, but removes 3]
>>> s
{1, 4}

您可以使用^=运算符执行相同的操作:

>>> s
{1, 4}
>>> s ^= set((4,))
>>> s
{1}
>>> s ^= set((4,))
>>> s
{1, 4}

更新:实现@Erwin Haasnoot提供的xorset

完整的不可变xorset实现,子类化frozenset,如下所示:

import itertools
from collections import Counter

class xorset(frozenset):
    def __new__(cls, it=()):
        it = (k for k, v in Counter(it).items() if v & 1)
        return super().__new__(cls, it)

    def add(self, v):
        return self ^ {v}

    def update(self, it):
        return self.__class__(itertools.chain(self, it))```

相关问题 更多 >