25

是否有一个库函数可以枚举 Python 中的素数(按顺序)?

我发现这个问题列出 N 以下所有素数的最快方法,但我宁愿使用别人的可靠库而不是自己滚动。我很乐意做import math; for n in math.primes:

4

5 回答 5

39

SymPy是另一种选择。它是一个用于符号数学的 Python 库。它为素数提供了几个功能。

isprime(n)              # Test if n is a prime number (True) or not (False).

primerange(a, b)        # Generate a list of all prime numbers in the range [a, b).
randprime(a, b)         # Return a random prime number in the range [a, b).
primepi(n)              # Return the number of prime numbers less than or equal to n.

prime(nth)              # Return the nth prime, with the primes indexed as prime(1) = 2. The nth prime is approximately n*log(n) and can never be larger than 2**n.
prevprime(n, ith=1)     # Return the largest prime smaller than n
nextprime(n)            # Return the ith prime greater than n

sieve.primerange(a, b)  # Generate all prime numbers in the range [a, b), implemented as a dynamically growing sieve of Eratosthenes. 

这里有些例子。

>>> import sympy
>>> 
>>> sympy.isprime(5)
True
>>> list(sympy.primerange(0, 100))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
>>> sympy.randprime(0, 100)
83
>>> sympy.randprime(0, 100)
41
>>> sympy.prime(3)
5
>>> sympy.prevprime(50)
47
>>> sympy.nextprime(50)
53
>>> list(sympy.sieve.primerange(0, 100))
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
于 2017-02-24T13:38:21.490 回答
17

gmpy2库有一个next_prime () 函数。这个简单的函数将创建一个生成器,该生成器将提供无限的素数:

import gmpy2

def primes():
    n = 2
    while True:
        yield n
        n = gmpy2.next_prime(n)

如果您将反复搜索素数,则创建和重用低于合理限制(例如 1,000,000)的所有素数的表会更快。这是另一个使用 gmpy2 和埃拉托色尼筛法创建素数表的示例。primes2() 首先从表中返回素数,然后使用 next_prime()。

import gmpy2

def primes2(table=None):

    def sieve(limit):
        sieve_limit = gmpy2.isqrt(limit) + 1
        limit += 1
        bitmap = gmpy2.xmpz(3)
        bitmap[4 : limit : 2] = -1
        for p in bitmap.iter_clear(3, sieve_limit):
            bitmap[p*p : limit : p+p] = -1
        return bitmap

    table_limit=1000000
    if table is None:
        table = sieve(table_limit)

    for n in table.iter_clear(2, table_limit):
        yield n

    n = table_limit
    while True:
        n = gmpy2.next_prime(n)
        yield n

您可以调整 table_limit 以满足您的需要。较大的值将需要更多内存并增加第一次调用 primes() 的启动时间,但重复调用会更快。

注意:我是 gmpy2 的维护者。

于 2012-11-11T03:09:27.577 回答
8

自从提出这个问题后,我围绕 C++ 库 primesieve 编写了一个 Python 包装器,该包装器继续被 primesieve 维护者采用。https://github.com/kimwalisch/primesieve-python

>>> from primesieve import *

# Generate a list of the primes below 40
>>> generate_primes(40)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]

# Generate a list of the primes between 100 and 120
>>> generate_primes(100, 120)
[101, 103, 107, 109, 113]

# Generate a list of the first 10 primes
>>> generate_n_primes(10)
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

# Generate a list of the first 10 starting at 1000
>>> generate_n_primes(10, 1000)
[1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061]

# Get the 10th prime
>>> nth_prime(10)
29

# Count the primes below 10**9
>>> count_primes(10**9)
50847534
于 2015-11-10T09:54:38.673 回答
1

我需要同样的东西,并决定创建自己的东西来锻炼很多东西。

这里:primes.py

警告:我尝试尽可能多地修复它并对所有内容进行检查,但我仍然是业余爱好者,所以我不保证高级或专业检查以及没有错误。使用风险自负。

它将根据需要动态筛选素数,以压缩二进制格式存储它们并从那里检索它们。

最有用的类是“素数”。类本身可以用作生成器、容器、下标和切片。

警告:小心迭代无限序列!

from primes import primes

for p in primes:  # 2, 3, 5, 7, 11, ...
    pass
primes[0]  # 2
primes[4]  # 11
primes[1:6:2] # primes object, generates 3, 7, 13
7 in primes  # True
8 in primes  # False

'primes 还有一些有用的方法:

primes.estimate(1000)  # 7830, real 1000th prime is 7927
primes.check(7)  # True
primes.index_of(11)  # 4 <- primes[4] = 11
primes.count_upto(10) # 4 <- len([2,3,5,7])
primes.sieve(5, 10)  # [5, 7] 
primes.in_range(5, 20, 2)  # primes object, generates 5, 11, 13, 19
primes.factor(12)  # {2:2, 3:1} <- 12 = 2^2 * 3^1
primes.phi(6)  # 6 <- Euler phi function,  number of smaller co-primes

素数对象本身是生成器、容器、可下标和可切片的,但在素数的子列表上:

primerange1 = primes(1, None, 2)  # generator
for p in primerange1:  # 3, 7, 13, 19, ...
    pass
primerange1[1]  # 7
primerange1[:4:-1]  # generator: 13, 7, 3
2 in primerange1  # False

primerange2 = primes(6, 0, -2)  # generates 13, 7, 3
len(primerange2)  # 3
reversed(primerange2)  # primes object, generates 3, 7, 13

'plib' 类用于管理库及其设置。

我希望有人会发现它有用,我很高兴收到任何建议或错误报告。

于 2021-09-06T15:45:01.170 回答
-1

没有恒定时间算法来生成下一个素数;这就是为什么大多数库都需要上限的原因。这实际上是数字密码学需要解决的一个巨大问题。RSA 通过选择一个随机数并测试素数直到找到一个素数来选择足够大的素数。

给定一个任意整数N,找到下一个素数的唯一方法N是迭代N+1到未知素数P测试素数。

测试素数非常便宜,并且有 python 库可以这样做:AKS Primes algorithm in Python

给定一个函数test_prime,一个无限素数迭代器看起来像:

class IterPrimes(object):
    def __init__(self,n=1):
        self.n=n

    def __iter__(self):
        return self

    def next(self):
        n = self.n
        while not test_prime(n):
            n += 1
        self.n = n+1
        return n

您可以使用许多启发式方法来加快该过程。例如,跳过偶数或可被 2、3、5、7、11、13 整除的数字等。

于 2012-11-11T03:38:08.040 回答