我正在执行多种类型的迭代:
masterSet=masterSet.union(setA)
随着集合的增长,执行这些操作所需的时间也在增长(正如人们所预料的那样,我猜)。
我希望花时间检查setA的每个元素是否已经在masterSet中?
我的问题是,如果我知道masterSet还没有包含setA中的任何元素,我可以更快地完成吗?
[UPDATE]
鉴于这个问题仍在吸引观点,我想我会从下面的评论和答案中清除一些内容:
迭代时虽然有很多次迭代我知道 setA
因为它的构造方式(不需要处理任何检查)而与masterSet
不同但是几次迭代我需要进行唯一性检查。
我想知道是否有办法'告诉'masterSet.union()
程序这次不打扰单一性检查,因为我知道这个与masterSet
不同,只需快速添加这些元素即可信任程序员的断言他们肯定是有害的。 Perhpas通过调用一些不同的“.unionWithDistinctSet()
”程序或其他东西。
我认为回复表明这是不可能的(无论如何真正设置操作应该足够快)但是使用masterSet.update(setA)
而不是union,因为它稍微快一点。
我接受了最清楚的回应,解决了我当时遇到的问题并继续我的生活,但仍然希望听到我的假设.unionWithDistinctSet()
是否能存在?
答案 0 :(得分:46)
您可以使用set.update
更新主集。这样可以节省分配新的集合,因此它应该比set.union
...
>>> s = set(range(3))
>>> s.update(range(4))
>>> s
set([0, 1, 2, 3])
当然,如果你在循环中这样做:
masterSet = set()
for setA in iterable:
masterSet = masterSet.union(setA)
通过执行以下操作可能会提升性能:
masterSet = set().union(*iterable)
最终,集合的成员资格测试是O(1)(在一般情况下),因此测试元素是否已经包含在集合中并不是真正的性能影响。
答案 1 :(得分:6)
如果您知道您的元素是唯一的,那么集合不一定是最佳结构。
一个简单的列表可以更快地扩展。
masterList = list(masterSet)
masterList.extend(setA)
答案 2 :(得分:4)
正如mgilson指出的那样,您可以使用update
从另一个集合中就地更新集合。这实际上有点快:
def union():
i = set(range(10000))
j = set(range(5000, 15000))
return i.union(j)
def update():
i = set(range(10000))
j = set(range(5000, 15000))
i.update(j)
return i
timeit.Timer(union).timeit(10000) # 10.351907968521118
timeit.Timer(update).timeit(10000) # 8.83384895324707
答案 3 :(得分:0)
当然,当__eq__(..)
方法非常昂贵时,放弃这项检查可能会有很大的节省。在CPython实现中,调用__eq__(..)
,其中集合中已经存在哈希到相同数字的每个元素。 (参考:source code for set
。)
然而,在一百万年内永远不会有这种功能,因为它开辟了另一种违反集合完整性的方式。与此相关的麻烦远远超过(通常可忽略的)性能增益。如果这被确定为性能瓶颈,那么编写C ++扩展并使用其STL <set>
并不难,它应该快一个或多个数量级。