试图制作一个Python 3素数生成器

时间:2014-05-12 20:28:54

标签: python python-3.x primes

正如标题所暗示的那样,我正在尝试制作一个支持Python 3的素数生成器,但我无法使其工作。

以下是代码:

import random
def main():
    d=1
    x=random.randint
    while True:
        d=d+1
        if isinstance(x/d, int)==True:
            print (x)
        else: main()
main()

和错误:

Traceback (most recent call last):
  File "/media/mint/casper-rw/ProjectsOrWork/Python/PrimeIdle.py", line 10, in <module>
    main()
  File "/media/mint/casper-rw/ProjectsOrWork/Python/PrimeIdle.py", line 7, in main
    if isinstance(x/d, int)==True:
TypeError: unsupported operand type(s) for /: 'method' and 'int'

2 个答案:

答案 0 :(得分:2)

代码位于底部,但请尝试根据以下建议编写自己的代码,这对您更有教育意义:

  1. x = random.randint实际上并未调用randint()
  2. 您希望继续生成整数候选项并测试素数。你应该在while循环中执行此操作,而不是每次候选测试复合时都递归到main()。这将导致无限的堆栈增长并最终溢出。 (如果您知道自己没有从中退回,请不要进行递归通话)。此外,您无法从一个非常深的递归链中轻松return ...您可以通过使用print(x)来回避这一点。
  3. 出于所有这些原因和良好的分解,将其分为名为generate_divisor()的生成器和谓词函数is_prime()(返回True / False)。
  4. 你的主循环:这里是如何使它非递归,并将其转换为while循环。对于任何整数x,您只需要通过(素数)除数直到floor(sqrt(x))来测试可除性。如果它不被任何这些除数整除,那么它就是素数,所以is_prime()落空并返回True。
  5. 您的可分性测试:if (isinstance(x/d, int)==True)不好,请注意大x / d上的截断错误,请使用if (x%d == 0)来测试可分性。
  6. 轻微:通过观察d> 5,你可以很容易地在你的黄金筛上获得60%的性能提升,素数只能在1,3,7或9结束。因此不要d = d+1 (或d += 1),你会产生大量的复合除数并减少少数素数。 (事实上​​,你正在产生大量的复合除数,如27或51,然后测试那些可分解性,这是完全浪费时间,因为你已经测试了3和17的可分性。)
  7. import random
    from math import sqrt, floor
    
    def generate_prime_candidate():
        """Generator to generate random prime candidate"""
        yield random.randint() # probably do randint(2, 2**32 -1). You decide.
    
    def find_random_prime():
        x = generate_prime_candidate()
        while not is_prime(x):
            x = generate_prime_candidate()
        # Found one!
        print(x)
        return x
    
    def is_prime(x):  # normally we call integers n, floats x, but whatever...
        for d in generate_divisors(floor(sqrt(x))): # only search up to sqrt(x)
            if x%d == 0:
                return False # x is composite - d is a divisor
            return True  # x is prime
    
    def generate_divisors(dmax):
        """Generate divisors, up to a limit. We exclude numbers easily known to be composite: residue 0,2,4,5,6,8 modulo 10"""
        yield 2
        yield 3
        yield 5 # now for d>5, exclude them by residue
        d = 7
        while d<dmax:
          while (d%10) == 5: # d easily known to be composite
            d += 2 # in fact we only need to test [0,2,4,6,8] not 5, since d+=2 is skipping residue 5 anyway
          yield d
    

答案 1 :(得分:1)

x=random.randint

不会将随机整数分配给x,它会分配 randint函数。你应该这样做:

x = random.randint(min, max)

然而,这是你遇到的最少的问题 - 你的主要考试不起作用,实际上并不是一个生成器函数,你在每次递归调用时都会选择一个新的随机数。