处理1000000+个元素的列表

时间:2017-08-02 02:13:57

标签: python list large-data

我正试图找到一种方法来查找prime gaps对低于100,000,000的素数的分布。

我的方法:

步骤1:从TXT文件开始" primes.txt"它有一个素数列表(最多10,000,000)。

步骤2:让程序读取文件,然后将每个数字插入列表 p1

步骤3:找到上限的平方根(TXT文件中素数上限的10倍,在本例中为100,000,000)并创建另一个列表 p2 ,全部小于或等于该平方根的素数,向上舍入。

步骤4:定义一个isPrime()方法,检查输入是否为素数( NB:,因为我知道要检查的数字都小于100,000,000,我只有检查该数字是否可以被小于或等于100,000,000的平方根的所有素数整除,即10,000)

步骤5:添加列表 l ,收集所有主要空白,然后从1到100,000,000迭代,检查每个数字的素数。如果数字是素数,则记录它与它之前的最后一个素数之间的差距,并将其写入另一个文件" primes2.txt"。

步骤6:输出列表 l

问题:

该程序似乎需要很长时间才能运行。我有一种感觉,问题与我如何管理列表有关,因为它的大小(Prime Number Theorem估计该列表中的620,420个元素来自" primes.txt")。有没有办法通过不同的方式处理列表来减少此程序的运行时间?

我已在下面附上我的代码。

import math
import sys

f = open("primes.txt","r")
p1 = []
for i in f:
    p1.append(int(i))
f.close()
ml = 10000000
ms = math.sqrt(10*ml)
p2 = []
x1 = 0
while x1 < len(p1) and p1[x1] <= int(ms+0.5):
    p2.append(p1[x1])
    x1 += 1

def isPrime(n):
    for i in p2:
        if n%i == 0:
            if n/i == 1:
                return True
            return False
    return True

def main():
    l = [0]*1001 #1,2,4,6,8,10,12,...,2000 (1, and then all evens up to 2000)
    lastprime = -1
    diff = 0
    fileobject = open("primes2.txt",'w')
    for i in xrange(1,10*ml):
        if isPrime(i):
            if i > 2:
                diff = i - lastprime
                if diff == 1:
                    l[0] += 1
                else:
                    l[diff/2] += 1
            lastprime = i
            fileobject.write(str(i)+"\n")
        if i%(ml/100) == 0:
            print i/float(ml/10), "% complete"
    fileobject.close()
    print l

main()

编辑:对程序从文件中读取的方式进行了更改

2 个答案:

答案 0 :(得分:1)

提示:

  1. 对于前几百万,你可以尽可能快地从文件中读取素数,但你需要有效地完成它。见下文。 (在我最近的MacBook Pro上生成n高达1亿,在Python中大约需要7秒。生成高达100,000,000的素数需要4分钟。在PyPy中会更快,在C中会更快方式或Swift或使用Numpy的Python)

  2. 你对记忆粗心。示例:ps = f.read().split('\n')然后使用p1 = [int(i) for i in ps]ps在未使用的内存中。浪费的。使用循环读取文件,以便更有效地使用内存。当您逐行阅读时,文件在转换后不会闲置在内存中。

  3. 有很好的理由认为大素数可用于加密;他们需要很长时间才能产生。 Python不是解决这个问题最有效的语言。

  4. 以下是Eratosthenes的筛子:

    def sieve_of_e(n):
        """ Returns  a list of primes < n """
        sieve = [True] * n
        for i in xrange(3,int(n**0.5)+1,2):
            if sieve[i]:
                sieve[i*i::2*i]=[False]*((n-i*i-1)/(2*i)+1)
        return [2] + [i for i in xrange(3,n,2) if sieve[i]]
    

答案 1 :(得分:0)

使用eratosthenes筛子升级主要功能。这是一个链接:

Sieve of Eratosthenes - Finding Primes Python