找到按原点分隔的 2 个集合的对称差异

问题描述 投票:0回答:1

我有两套:

>>> a = {1,2,3}
>>> b = {2,3,4,5,6}

我想获得two带有常见元素的新集合,第一个集合包含来自

a
的元素,第二个包含来自
b
的元素,如
({1}, {4,5,6})
,或类似:

>>> c = a&b # Common elements
>>> d = a^b # Symmetric difference
>>> (a-b, b-a)
({1}, {4, 5, 6})
>>> (a-c, b-c)
({1}, {4, 5, 6})
>>> (a&d, b&d)
({1}, {4, 5, 6})

我的问题是我将在大量 sha1 哈希上使用它,并且我担心性能。 有效地做到这一点的正确方法是什么?

注意:

a

b
将有大约95%的共同元素,1%将在
a
中,4%将在
b
中。

python python-3.x performance set symmetric-difference
1个回答
2
投票
我在问题中提到的方法具有以下性能:

>>> timeit.timeit('a-b; b-a', 'a=set(range(0,1500000)); b=set(range(1000000, 2000000))', number=1000) 135.45828826893307 >>> timeit.timeit('c=a&b; a-c; b-c', 'a=set(range(0,1500000)); b=set(range(1000000, 2000000))', number=1000) 189.98522938665735 >>> timeit.timeit('d=a^b; a&d; b&d', 'a=set(range(0,1500000)); b=set(range(1000000, 2000000))', number=1000) 238.35084129583106
所以最有效的方法似乎是使用

(a-b, b-a)

方法。

我将其发布作为参考,以便其他答案会添加新方法,而不是比较我找到的方法。


Python实现的功能

出于好奇,我尝试实现自己的 python 函数来执行此操作(适用于预排序的迭代器):

def symmetric_diff(l1,l2): # l1 and l2 has to be sorted and contain comparable elements r1 = [] r2 = [] i1 = iter(l1) i2 = iter(l2) try: e1 = next(i1) except StopIteration: return ([], list(i2)) try: e2 = next(i2) except StopIteration: return ([e1] + list(i1), []) try: while True: if e1 == e2: e1 = next(i1) e2 = next(i2) elif e1 > e2: r2.append(e2) e2 = next(i2) else: r1.append(e1) e1 = next(i1) except StopIteration: if e1==e2: return (r1+list(i1), r2+list(i2)) elif e1 > e2: return (r1+[e1]+list(i1), r2+list(i2)) else: return (r1+list(i1), r2+[e2]+list(i2))
与其他方法相比,这种方法的性能相当低:

t = timeit.Timer(lambda: symmetric_diff(a,b)) >>> t.timeit(1000) 542.3225249653769
因此,除非在某处实现了其他方法(一些用于处理集合的库),我认为使用两个集合的差异

执行此操作的最有效方法。

© www.soinside.com 2019 - 2024. All rights reserved.