Python 为什么set()使这段代码运行得更快?

Python 为什么set()使这段代码运行得更快?,python,performance,set,Python,Performance,Set,我为Project Euler编写了一些代码: 我的初始代码(没有b=set(primes))运行了很长时间,我没有等它完成。我很好奇,为什么这两段代码在运行时间上存在如此大的差异,因为我不相信primes会有任何重复项,这会使迭代花费如此长的时间,以至于迭代set(primes)。也许我对set()的想法是错误的。欢迎任何帮助。我相信这里的罪魁祸首是,如果int(a)不在b:。集合在内部实现为哈希表,这意味着检查成员资格比使用列表要便宜得多(因为您只需要检查冲突) 你可以查看集合的内部。检查集

我为Project Euler编写了一些代码:


我的初始代码(没有
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