我怎样才能加快我的python程序?

时间:2014-10-04 17:32:49

标签: python-3.x

我试图在Python 3.4.1中创建一个程序,以获得2到100,000的素数。

我的问题是处理所有信息需要花费太多时间,而且从来没有给我任何结果。

我离开了大约半个小时,它使我的所有计算机都变慢了,它没有给我我想要的东西。

我正在使用Eratosthenes的Sieve算法"Criba de Eratostenes"

这是我的代码:

from math import *

def primos(num):
    num2     = num + 1
    tnumeros = []                      # tnumeros  = every number from 2 to num
    npnumeros= []                      # npnumeros = every number that is no prime
    pnumeros = []                      # pnumeros  = every prime number

    for a in range( 2, num2 ):
        tnumeros.append( a )

    for i in range( 2, int( sqrt( num ) ) + 1 ):
        for j in range( i, int( num / i ) + 1 ):
            np = i * j
            npnumeros.append( np )

    npnumeros = list( set( npnumeros ) )

    for e in tnumeros:
        if ( e in npnumeros ):
            continue
        else:
            pnumeros.append( e )

    return ( str( "".join( str( pnumeros ) ) ) )

print( primos( 100000 ) )

2 个答案:

答案 0 :(得分:1)

请勿使用npnumeros值列表;改用一套。你只想查看一个数字是否在该集合中,所以从一开始就把它作为一个集合:

npnumeros = set()
# ...
for i in range( 2, int( sqrt( num ) ) + 1 ):
    for j in range( i, int( num / i ) + 1 ):
        np = i * j
        npnumeros.add( np )

# npnumeros = list( set( npnumeros ) )  # Remove this line, it's no longer needed

for e in tnumeros:
    if ( e in npnumeros ):
        continue
    else:
        pnumeros.append( e )

你的代码很慢的原因是查找列表中的数字是O(N)时间,而在O(N)循环中查找数字是O(N ^ 2)时间。但是在一组中查找数字是O(1)时间,因此你将在该循环内有O(N)时间。从O(N ^ 2)到O(N)将代表处理速度的巨大差异。

如果您不理解我使用的O(N)符号,Google "Big O notation"可以阅读更多相关信息。

答案 1 :(得分:0)

这是一个严重截断的答案,因为这个问题可能应该转移到CR。

快速加速只是将npnumeros作为一组而不是列表。这意味着后来的计算if ( e in npnumeros ):会更快地发生。

修改后的代码:

from math import *

def primos(num):
    num2     = num + 1
    tnumeros = []                      # tnumeros  = every number from 2 to num
    npnumeros= []                      # npnumeros = every number that is no prime
    pnumeros = []                      # pnumeros  = every prime number

    for a in range( 2, num2 ):
        tnumeros.append( a )

    for i in range( 2, int( sqrt( num ) ) + 1 ):
        for j in range( i, int( num / i ) + 1 ):
            np = i * j
            npnumeros.append( np )

    npnumeros = set( npnumeros )

    for e in tnumeros:
        if ( e in npnumeros ):
            continue
        else:
            pnumeros.append( e )

    return ( str( "".join( str( pnumeros ) ) ) )

print( primos( 100000 ) )

跑得快〜60倍。