Python 求按原点分隔的两个集合的对称差
我有两套:Python 求按原点分隔的两个集合的对称差,python,performance,python-3.x,set,Python,Performance,Python 3.x,Set,我有两套: >>> a = {1,2,3} >>> b = {2,3,4,5,6} 我想得到两个带有非公共元素的新集合,第一个集合包含a中的元素,第二个集合包含b中的元素,比如({1},{4,5,6}),或者类似的: >>> c = a&b # Common elements >>> d = a^b # Symmetric difference >>> (a-b, b-a) ({1}, {4, 5
>>> a = {1,2,3}
>>> b = {2,3,4,5,6}
我想得到两个带有非公共元素的新集合,第一个集合包含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
中,我在问题中提到的方法具有以下性能:
>>> 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
t = timeit.Timer(lambda: symmetric_diff(a,b))
>>> t.timeit(1000)
542.3225249653769
所以最有效的方法似乎是使用(a-b,b-a)
方法
我将此作为参考发布,以便其他答案会添加新方法,而不是比较我发现的方法
Python实现的函数 出于好奇,我尝试实现自己的python函数来实现这一点(在预排序迭代器上工作): 与其他方法相比,此方法的性能非常低:
>>> 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
t = timeit.Timer(lambda: symmetric_diff(a,b))
>>> t.timeit(1000)
542.3225249653769
因此,除非在某个地方实现了其他方法(一些用于处理集合的库),否则我认为使用两个集合的差异是最有效的方法。
a-b,b-a
是我过去这样做的方法,但这是为了可读性而不是性能。你为什么不试试其中的几种方法,然后在timeit
中逐一运行呢?我认为你无法击败a-b,b-a
。Python所要做的就是计算名称a
和b
,然后用-
进行二进制减法(您可以用查看确切的细分)。然而,创建新集合的实际函数是用C编写的,这将比用Python编写的任何函数都要好。我认为a-b,b-a
将是O(n),无论如何,我无法想象有任何方法比O(n)
更好。用一次迭代而不是两次迭代不会改变复杂性。无论如何,这是一个有趣的问题,在更新关系数据库上的多对多时,我经常需要这样做,以确定要添加/修改/删除哪些元素