Python中的Palindrome / Prime Checker无法正常工作

时间:2014-04-12 14:40:41

标签: python algorithm loops

我的任务是:

  

在base-2(二进制)和base-10(十进制)中,唯一(两位数或以上)Prime数是什么回文符号   实例吗

每当我运行此代码时,没有任何反应,它就像一个无限循环。我做错了什么,或者我该如何改进? 非常感谢提前。

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

--------- 编辑:**已解决** --------- < / p>

修改后的代码:

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

感谢所有提供答案的人。

1 个答案:

答案 0 :(得分:7)

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 Function for Python Language你的isPrime()函数的建议会更快一些:

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

你可以放弃测试基础10回文,因为发生器只产生 回文。