Python 为什么set()使这段代码运行得更快?
我为Project Euler编写了一些代码:Python 为什么set()使这段代码运行得更快?,python,performance,set,Python,Performance,Set,我为Project Euler编写了一些代码: 我的初始代码(没有b=set(primes))运行了很长时间,我没有等它完成。我很好奇,为什么这两段代码在运行时间上存在如此大的差异,因为我不相信primes会有任何重复项,这会使迭代花费如此长的时间,以至于迭代set(primes)。也许我对set()的想法是错误的。欢迎任何帮助。我相信这里的罪魁祸首是,如果int(a)不在b:。集合在内部实现为哈希表,这意味着检查成员资格比使用列表要便宜得多(因为您只需要检查冲突) 你可以查看集合的内部。检查集
我的初始代码(没有
b=set(primes)
)运行了很长时间,我没有等它完成。我很好奇,为什么这两段代码在运行时间上存在如此大的差异,因为我不相信primes
会有任何重复项,这会使迭代花费如此长的时间,以至于迭代set(primes)
。也许我对set()的想法是错误的。欢迎任何帮助。我相信这里的罪魁祸首是,如果int(a)不在b:
。集合在内部实现为哈希表,这意味着检查成员资格比使用列表要便宜得多(因为您只需要检查冲突)
你可以查看集合的内部。检查集合中的
包含是常数时间,而列表中最坏的情况是线性时间,这就是我假设你从函数siever\u erat
返回的时间。请看。作为一个旁注,你可以利用素数列表已排序的事实来加快速度(sieve_erat
生成它本身)。可能重复@hlove Yes,正如jmduke所说。对于列表,成员资格测试扫描(可能是整个)列表,对于set,它是一个执行时间恒定的操作,因为set的hash作为数据库索引排序。
#Project Euler: Problem 35
import time
start = time.time()
def sieve_erat(n):
'''creates list of all primes < n'''
x = range(2,n)
b = 0
while x[b] < int(n ** 0.5) + 1:
x = filter(lambda y: y % x[b] != 0 or y == x[b], x)
b += 1
else:
return x
def circularPrimes(n):
'''returns # of circular primes below n'''
count = 0
primes = sieve_erat(n)
b = set(primes)
for prime in primes:
inc = 0
a = str(prime)
while inc < len(a):
if int(a) not in b:
break
a = a[-1] + a[0:len(a) - 1]
inc += 1
else:
count += 1
else:
return count
print circularPrimes(1000000)
elapsed = (time.time() - start)
print "Found in %s seconds" % elapsed
def circularPrimes(n):
'''returns # of circular primes below n'''
count = 0
primes = sieve_erat(n)
for prime in primes:
inc = 0
a = str(prime)
while inc < len(a):
if int(a) not in primes:
break
a = a[-1] + a[0:len(a) - 1]
inc += 1
else:
count += 1
else:
return count