【问题标题】:Palindrome/Prime Checker in Python not workingPython中的回文/素数检查器不起作用
【发布时间】:2014-05-26 17:50:08
【问题描述】:

我的任务是这样的:

在 base-2(二进制)和 base-10(十进制)中唯一(两位数或以上)回文的素数是什么 实例?

每当我运行这段代码时,什么都没有发生,它就像一个无限循环。我做错了什么,或者我该如何改进? 非常感谢。

def isPrime(n):
    if type(n) != int or n <= 1:
        return False
    elif n == 2:
        return True
    elif n%2 == 0:
        return False
    else:
        for x in range(2, int(n**0.5)+1):
            if n%x == 0:
                return False
                break
        return True
def isPalindrome(x):
    num = str(x)[::-1]
    if str(x) == num:
        return True
    else:
        return False
while True:
    a = 11
    if isPrime(a) and isPalindrome(a) == True:
        if isPalindrome(bin(a)) == True:
            print a
            break
    else:
        a+=2
        print a

--------- 编辑:**已解决** ---------

修改后的代码:

def isPrime(n):
    if n < 2 or n%2 == 0:
        return False
    if n == 2:
        return True
    else:
        for x in range(3, int(n**0.5)+1, 2):
            if n%x == 0:
                return False
        return True
def isPalindrome(x):
    num = str(x)[::-1]
    return str(x) == num
a = 11
while True:
    if isPrime(a) and isPalindrome(a) and isPalindrome(format(a, "b")):
            print a
            break
    a+=2

感谢所有提供答案的人。

【问题讨论】:

  • return 后面的break 是多余的,因为return 已经返回函数值并且for 完成
  • 是打印“a”的值还是根本没有输出?
  • 不相关,来自PEP 8:使用isinstance(obj, int) 来检查obj 是否为整数并删除== True
  • 额头拍打从来没有想过这个。谢谢! @RubenBermudez
  • 我相信它应该在 while 循环中通过两个 if 语句后打印“a”。即使没有通过,它也应该打印“a”,所以我可以看到它的进度。 @Sirac

标签: python algorithm loops


【解决方案1】:

bin() 的输出绝不是回文,因为字符 0b 被添加到它前面:

>>> bin(3)
'0b11'
>>> isPalindrome(bin(3))
False

要么对这两个字符进行切片,要么使用format() 生成二进制表示:

>>> format(3, 'b')
'11'
>>> isPalindrome(format(3, 'b'))
True

您的循环还有另一个问题:如果您发现一个不是以 2 为底的回文素数,它不会增加:

if isPrime(a) and isPalindrome(a) == True:
    if isPalindrome(format(a, 'b')) == True:
        print a
        break
    # no else here
else:
    a+=2
    print a

只需在一次测试中测试所有条件:

if isPrime(a) and isPalindrome(a) and isPalindrome(format(a, 'b')):
    print a
    break
a += 2

很少需要在布尔测试中测试 == True

接下来是你在循环中重置 a

while True:
    a = 11

在循环的其余部分你对a 做了什么并不重要,在顶部它会回到 11。将它移出循环:

a = 11
while True:
    if isPrime(a) and isPalindrome(a) and isPalindrome(format(a, 'b')):
        print a
        break
    a += 2

每当您写if comparison: return True 后跟else: return False 时,只需返回测试

def isPalindrome(x):
    num = str(x)[::-1]
    return str(x) == num

因为==比较运算符已经返回一个布尔值。

您的素数测试不需要测试n 的类型,实际上(您只传递整数),但测试类型的正确方法是使用:

isinstance(n, int)

因为这也允许int 的子类。即使您确实需要将某些内容限制为非常特定的类型并且不能允许子类,您也可以使用:

type(n) is int

因为类型是单例。

如果您使用 isPrime() 函数,从 isPrime Function for Python Language 获取建议会更快一些:

def isPrime2(n):
    if n < 2: return False
    if n == 2: return True
    for i in range(3, int(n ** 0.5) + 1, 2):   # only odd numbers
        if n % i == 0:
            return False
    return True

改为。

通过限制您查看的值的数量,可以使您的循环更有效率。如果您查看 OEIS 上的 Palindronic Prime series,您会发现除了 11,所有以 10 为底的回文素数都有奇数位数,因此您可以跳过大量数字。以下将产生更好的候选人:

def palindromic_candidates():
    yield 11
    outer = 1
    while True:
        for i in range(10):
            yield int('{}{}{}'.format(outer, i, str(outer)[::-1]))
        outer += 1

演示:

>>> from itertools import islice
>>> pc = palindromic_candidates()
>>> list(islice(pc, 30))
[11, 101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323, 333, 343, 353, 363, 373, 383]
>>> list(islice(pc, 100, 130))
[13931, 14041, 14141, 14241, 14341, 14441, 14541, 14641, 14741, 14841, 14941, 15051, 15151, 15251, 15351, 15451, 15551, 15651, 15751, 15851, 15951, 16061, 16161, 16261, 16361, 16461, 16561, 16661, 16761, 16861]

使用这个代替 while True 循环,删除 a += 2 行:

for a in palindromic_candidates():
    if isPrime(a) and isPalindrome(format(a, 'b')):
        print a
        break

当生成器生成回文时,您可以放弃对 base-10 回文的测试。

【讨论】:

  • 在 while 循环中使用 a=11 时,始终检查数字 11 是否为素数、回文和二进制回文。如果不是13 正在打印并再次检查11a=11 应该在 while 循环之外。
  • @MartijnPieters 您使用该网站的时间比我长,这样的问题(需要解决的问题很多很多)会被视为离题吗?
  • @AlexThornton:不是这样; OP在这里没有问多个问题。他们没有意识到的问题不止一个。
  • @MartijnPieters 哇 - 不知道我有这么多问题!作为一个没有经验的 14 岁的我,这是应该预料到的。感谢您花时间输入如此清晰而详细的回复,这非常有帮助。将发布完成的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
  • 2022-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-22
  • 1970-01-01
相关资源
最近更新 更多