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

hlo*_*ove 2 python performance set

我为Project Euler 问题35写了一些代码:

#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
Run Code Online (Sandbox Code Playgroud)

我很奇怪,为什么这个代码(以上)运行如此之快,当我设置b = set(primes)的circularPrimes功能.此代码的运行时间约为8秒.最初,我没有设置b = set(primes),我的circularPrimes功能是这样的:

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
Run Code Online (Sandbox Code Playgroud)

我的初始代码(没有b = set(primes))运行了很长时间,我没有等到它完成.我很好奇为什么在两段代码之间的运行时间方面存在如此大的差异,因为我不相信primes会有任何重复,这会使迭代需要花费更长的时间来迭代set(primes).也许我对set()的想法是错误的.欢迎任何帮助.

jmd*_*uke 5

我相信这里的罪魁祸首if int(a) not in b:.集合在内部实现为哈希表,这意味着检查成员资格比使用列表要便宜得多(因为您只需要检查冲突).

你可以在这里看看内部的内部.