在我的程序中,我需要将[1, 10**5)
范围内的数字对存储在一组中,并对其进行多次查找。我可以将它们作为元组添加到集合中:
seen = set()
seen.add((x, y))
(x, y) in seen # True
,但是有一种更有效的方法,例如使用由两个数字组成的数字/字符串键?
答案 0 :(得分:0)
AFAIK OP的方法几乎是最有效的。集合对它们的内容进行哈希处理,使查找具有恒定的复杂性,而元组由于其内部结构又小又快,因此对一对冻结对象使用冻结集(可哈希化,因此可以作为集合的元素)并不是没有道理的。价值观。因此,除非您对元组的顺序有问题(不是无序的),否则您就很好。
答案 1 :(得分:0)
似乎将数字组合是最快的方法(比在测试中使用元组快约2倍):
seen = set()
seen.add(x*10**5+y)
x*10**5+y in seen # True
P.S。为了测试它,我在ipython中的以下两个函数上使用了%timeit
:
def f1():
seen = set()
for x in range(1000):
for y in range(1000):
seen.add((x, y))
assert (x, y) in seen
def f2():
seen = set()
for x in range(1000):
for y in range(1000):
seen.add(x*10**5+y)
assert x*10**5+y in seen
结果:
In [2]: %timeit f1()
466 ms ± 1.08 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [3]: %timeit f2()
254 ms ± 1.63 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
答案 2 :(得分:0)
虽然将数字组合在一起(x * 10 ** 5 + y)可以提供更好的性能,但可能更难调试集合中的问题。比元组更快但比数字组合慢一点的替代方法是使用字典:
def f3():
seen = dict()
for x in range(1000):
for y in range(1000):
seen.setdefault(x,set()).add(y) # insert a new pair
assert x in seen and y in seen[x] # check if pair in dictionary
此f3()函数的时间为0.284秒,而f2()的时间为0.248秒(因此不会造成很大的性能损失)。它还使您能够轻松列出任何给定x的y值。
编辑
使用defaultdict确实可以使其更快。它甚至比数字组合(0.126)快,比一组元组快4倍。
from collections import defaultdict
def f4():
seen = defaultdict(set)
for x in range(1000):
for y in range(1000):
seen[x].add(y) # insert a new pair
assert y in seen[x] # check if pair in dictionary