【问题标题】:Storing lots of data in a Python list在 Python 列表中存储大量数据
【发布时间】:2018-03-07 13:13:34
【问题描述】:

我想要一个程序来生成最高 10^9 的素数。 我正在使用 Eratosthenes 的 Sieve 在 python 中实现它,但是当我尝试 10^9 时出现内存错误。它工作正常,直到 10 ^ 7。 这是我正在使用的代码

def prime(n):
    p=[True]*(n+1)
    p[0]=p[1]=False

    for i in range(int(n**0.5)+1):
        if p[i]:
            for j in range(i*i, n+1, i):
                p[j] = False

    for i in range(n+1):
        if p[i]:
            yield i

我使用的是 6GB 内存的 Windows 10

【问题讨论】:

  • 你用的是64位还是32位的python?前段时间我自己解决了内存问题,并通过切换到 64 位 python 来解决。另外:除非你不得不,否则用python脚本吃掉这么多内存并不是一个好主意
  • @MaLiN2223 64 位。
  • 你可能想试试 NumPy 数组
  • 您可以尝试使用分段筛。它对内存更友好。如果我没记错的话,有一个使用生成器的聪明的 python 实现。
  • 如果您使用的是 Python 2,那么在两个循环中都更喜欢 xrange 而不是 range

标签: python algorithm sieve-of-eratosthenes


【解决方案1】:

您可以通过仅存储素数本身来获得巨大的加速,而不是在每个特定的素数上存储真或假。这将大大简化您的程序,并且还应该允许您处理更大的值。

替代方法

尝试编译一个素数列表,然后只测试这些素数,看看我们是否有任何除数。这明显更快,我在这里没有内存问题,我尝试了 prime(655360002) (我在维基百科上查找)没有问题。

def prime(n):

    found_primes = []
    for number in range(2, int(n**0.5)+1):

        number_is_prime = True

        # The new number can only be divisible by other primes
        for divisor in found_primes:
            if number % divisor == 0:
                number_is_prime = False
                break

        if number_is_prime:
            found_primes.append(number)


    # Now that we have a list of primes, we test our number against them
    for prime in found_primes:
        if n % prime == 0:
            return False


    # IF we tried all primes, then we must be prime
    return True

【讨论】:

  • 好建议。 OP,在我的系统上调用 sys.getsizeof(True) 显示每个布尔值是 24 个字节。 10^9 个布尔值是 24GB……系统内存增加三倍!正如其他人所建议的那样,numpy 数组可能更有效,但存储这些值会削弱您的系统。
  • 我同意。最糟糕的部分是 p=[True]*(n+1)
  • 是的,这是基本问题,初始步骤分配了大量不需要的内存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多