【问题标题】:count output of a function python计算函数python的输出
【发布时间】:2015-02-12 07:07:56
【问题描述】:

我正在使用以下代码来测试素数。

def primes(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)
    yield [2] + [i for i in xrange(3,n,2) if sieve[i]]


outfile = open('primes','w')
input = input("Feed Me:")

outfile.write(str(primes(input)))
print "Done"

有没有一种简单的方法来计算生成的素数。而不是打印实际数字? 也可以让这段代码生成大于 100000000 的素数而不会溢出吗?

【问题讨论】:

  • FWIW,您的代码只产生一个对象(一个列表),因此您应该将 yield 更改为 returnyield 语句用于制作生成器;请参阅the docs 了解更多信息。
  • 是的,那是在我乱搞的时候发生的。我更改了一些代码并不得不将其更改回来。然后我发布了愚蠢的版本。 :(

标签: python math memory-management


【解决方案1】:

您可以从表中删除每个偶数,只需将整数除以2 即可仅存储奇数。 sum 与将它们映射到整数的布尔值一起使用:True 为 1,False 为 0;请注意,即使在 n >= 2 的表中没有 2 时,这仍然有效,因为 1 在表中被标记为素数;)

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

    return sum(sieve)

或者更好的是,计算遇到的素数:

def n_primes(n):
    """ Returns  the number of primes < n (for n > 2)"""
    n_p = 1  # 2 is a prime
    sieve = [True] * (n//2)
    for i in xrange(3,int(n**0.5) + 1,2):
        if sieve[i//2]:
            n_p += 1
            sieve[i*i//2::i]=[False]*((n-i*i-1)/(2*i)+1)

    return n_p

请注意,您的 sieve 函数不返回列表,而是返回生成结果的生成器,您可能希望将原始代码编写为

def primes(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]]

或使用我的生成器版本:

def primes(n):
    """ Yields a sequence of primes < n """
    if n <= 2:
        return

    yield 2
    sieve = [True] * (n//2)
    for i in xrange(3,int(n**0.5) + 1,2):
        if sieve[i//2]:
            yield i
            sieve[i*i//2::i] = [False] * ((n-i*i-1)/(2*i)+1)

对于第一种情况,您可以通过len(primes(n)) 获取号码(虽然这样做很浪费),对于第二种情况,您可以使用sum(1 for i in primes(n))


至于在100000000 之上生成素数,sieve 表将在 32 位处理器上花费 (4 * n / 2) 字节,在 64 位处理器上花费 8 * n / 2,因此您的里程可能会有所不同......有人会想要使用某种bitarray 虽然不是python内置的。

【讨论】:

  • 到目前为止很好,但我仍然在 1000000000 标记附近遇到内存错误。我最终要找的号码是:18446744073709551615
  • 祝你好运。 18446744073709551615 是 2^64 位,存储筛子需要 2^60 字节,顺便说一下是 1048576 TiB。按照目前的硬盘价格,存储这些数据将花费大约 3500 万美元。
  • 您可以使用我去年发布的this code 来查找某个范围内的大素数,例如python range_sieve6.py 1234567890000 1234567890100 在我的2GHz 机器上在3.5 秒内返回[1234567890007L, 1234567890019L, 1234567890041L, 1234567890089L, 1234567890097L]。但它对于调查您感兴趣的巨大大小的数字没有用处。
  • @user34981:要通过试除法分解 5 的素数都采用 30k±r 的形式,其中 r 在 {1, 7, 11, 13} 中)。 FWIW,我这里有一个最多 3000000000 个素数的数据库,所以这是 100E6 字节。但是,对大量执行这些试验分区可能需要 很长时间 时间。
  • @user34981:大数的有效分解需要相当高级的数学。一种流行的算法是Lenstra elliptic curve factorization。另见en.wikipedia.org/wiki/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-14
  • 2021-07-31
  • 1970-01-01
  • 1970-01-01
  • 2019-06-15
  • 2021-12-19
  • 2013-03-02
相关资源
最近更新 更多