Python镜像质数生成器

3

我正在参加一门Python编程课程,上周我们得到了一个作业问题,要求开发一个程序来生成所有小于或等于n的素数,其镜像也是素数,我不知道哪里出错了,请帮忙!

import math

def mirror_prime(n):
    answer = True
    # Test 0 and 1
    if n==0 or n==1:
        answer = False
    # End if

    # Test even numbers
    if n != 2 and n%2==0:
        answer= False
    # End if

    # Test if there is a proper odd divisor
        for d in range (3, int(math.sqrt(n))+1, 2):
            if n%d==0:
                answer=False
            # End if
        # End for



    #Reverse n
    mirror_n = int(str(n)[::-1])
    mirror_answer = True

    # Test 0 and 1
    if mirror_n==0 or mirror_n==1:
        mirror_answer = False
    # End if


def mirror_prime_generator(n):
    for i in range(3, n+1):
        print (mirror_prime(i))

我希望获得一个素数列表,这些素数的镜像也是素数,小于或等于 n。

当我在shell中输入mirror_prime_generator(n)时,得到的结果只是打印none,不管n是多少次,因此如果n是23,它将打印23次none。


你需要使用 return mirror_answer 返回答案。如果你没有返回任何值,那么默认值是 None,这就是你要打印的内容。 - larsr
我应该把它放在哪里?当我将其放入第一个def并运行时,它只会打印True或False,而不是数字。 - Clonemyster
1
你的程序中还有一些其他的错误。尝试弄清楚程序为什么会出现这种情况是一个很好的练习。但首先,你有时将值分配给名为“answer”的变量,有时又分配给“mirror_answer”。它们可能应该是相同的。其次,只有在mirror_prime返回True时,你才应该打印i(数字)。 - larsr
哦,好的,谢谢。如果我需要打印两个不同的值,质数和镜像质数,我不需要有两个不同的变量吗?还要感谢您的帮助! - Clonemyster
实际上,一旦您确定一个数字不是质数,就可以立即返回False,然后没有必要进行其他测试。但是您可以执行所有测试并使用两个变量,但然后您应该返回answer and mirror_answer,当且仅当answermirror_answer都为True时才为True - larsr
OP,这是一个不错的尝试,但我认为你可能需要回到起点重新开始。可以这样想,首先列出从1到n的数字列表。然后过滤掉所有非质数。接着再过滤掉所有非镜像数字。剩下的就是小于n的镜像质数列表了。总的来说,我认为将复杂的问题分解成连续的步骤是个好主意。 - Robert Dodier
4个回答

2

还存在一些错误。 for 循环的缩进是错误的(它们在 if 内部),有时会使用 n 而不是 mirror_n

你的代码

这是一个只做了最少更改的可行代码:

import math

def mirror_prime(n):
    answer = True
    # Test 0 and 1
    if n==0 or n==1:
        answer = False
    # End if

    # Test even numbers
    if n != 2 and n%2==0:
        answer= False
    # End if

    # Test if there is a proper odd divisor
    for d in range (3, int(math.sqrt(n))+1, 2):
        if n%d==0:
            answer=False
        # End if

    # End for

    #Reverse n
    mirror_n = int(str(n)[::-1])
    mirror_answer = True

    # Test 0 and 1
    if mirror_n==0 or mirror_n==1:
        mirror_answer = False
    # End if
    # Test even numbers
    if mirror_n != 2 and mirror_n%2==0:
        mirror_answer= False
    # End if

    # Test if there is a proper odd divisor
    for d in range (3, int(math.sqrt(mirror_n))+1, 2):
        if mirror_n%d==0:
            mirror_answer=False
        # End if

    # End for

    if answer and mirror_answer==True:
        return n, mirror_n



def mirror_prime_generator(n):
    for i in range(3, n+1):
        if mirror_prime(i):
            print(i)

mirror_prime_generator(100)
# 3
# 5
# 7
# 11
# 13
# 17
# 31
# 37
# 71
# 73
# 79
# 97

简短版

尽量避免使用重复的代码。对于nmirror_n的测试是完全相同的,因此您可以将其放在一个函数中:

def is_prime(n):
    if n == 2:
        return True
    if n < 2 or n % 2 == 0:
        return False
    for d in range(3, int(n**0.5) + 1, 2):
        if n % d == 0:
            return False
    return True


def is_mirror_prime(n):
    mirror_n = int(str(n)[::-1])
    return mirror_n != n and is_prime(n) and is_prime(mirror_n)

print([n for n in range(1000) if is_mirror_prime(n)])
# [13, 17, 31, 37, 71, 73, 79, 97, 107, 113, 149, 157, 167, 179, 199, 311, 337, 347, 359, 389, 701, 709, 733, 739, 743, 751, 761, 769, 907, 937, 941, 953, 967, 971, 983, 991]

0

我认为定义你所描述的函数的最短方式是这样的:

def mirrorPrimes(limit):
    primes = [n for n in range(2,limit+1) if all(n%d!=0 for d in range(2,n))]
    return [n for n in primes if int(str(n)[::-1]) in primes]

第一行函数将从2到limit的所有质数放入primes,第二行仅在primes中存在镜像时返回元素。

简单而干净!


0
你必须考虑你想让你的函数做什么。据我所知,函数mirror_prime(n)回答了问题“n和它的镜像质数是否都是质数?”,这是一个二元问题(真或假)。如果是这种情况,这是完全合理的,那么请按照以下方式重构你的mirror_prime_generator循环:
def mirror_prime_generator(n):
    for i in range(3, n+1):
        if mirror_prime(i):
            print(i)

当然,这是建立在mirror_prime确实返回正确结果的前提下,但这似乎是你整个任务的核心,所以我不会再多说了。

1
这不是一个好的答案,因为程序还有其他错误,而且OP想要找出更好的结构。如果他只是复制这段代码,它仍然不能实现他想要达到的目标。 - Mr. T
非常感谢,我终于搞清楚了。在编辑后还有一些错误,但那是我的疏忽,因为我忘记更改某些变量名称和其他东西。 - Clonemyster
我必须在第一个定义中做一些改变,比如改变一些 if 语句和添加更多的测试。 - Clonemyster

0

这是我编辑后的代码,现在它做到了我想要的功能,感谢大家的帮助。

import math

def mirror_prime(n):
    answer = True
    # Test 0 and 1
    if n==0 or n==1:
        answer = False
    # End if

    # Test even numbers
    if n != 2 and n%2==0:
        answer= False
    # End if

    # Test if there is a proper odd divisor
    for d in range (3, int(math.sqrt(n))+1, 2):
        if n%d==0:
            answer=False
        # End if

    # End for





    #Reverse n
    mirror_n = int(str(n)[::-1])
    mirror_answer = True

    # Test 0 and 1
    if mirror_n==0 or mirror_n==1:
        mirror_answer = False
    # End if
    # Test even numbers
    if n != 2 and n%2==0:
        mirror_answer= False
    # End if

    # Test if there is a proper odd divisor
    for d in range (3, int(math.sqrt(mirror_n))+1, 2):
        if mirror_n%d==0:
            mirror_answer=False
        # End if

        # End for

    if answer and mirror_answer==True:
        return n, mirror_n



def mirror_prime_generator(n):
    for i in range(3, n+1):
        if mirror_prime(i):
            print(i)

这段代码还是有问题的。for 应该在 if 的外面。 - Eric Duminil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接