Python实现回文数与质数判定:从基础逻辑到性能优化

林见深
林见深
发布时间:2026-10-13 | 2人浏览过
原创

本文深入解析Python中判断回文数与质数的实现方法,重点剖析for...else语句的常见误用及其对结果的影响。通过对比正确与错误代码,阐述算法优化策略,并展示四种不同嵌套逻辑的性能差异,帮助开发者避免逻辑陷阱并提升代码效率。

前言:问题背景与调试回顾

一、前言

在观看视频教程进行课后练习时,任务要求找出1000以内既是素数又是回文数的数字。编写代码看似简单,但运行结果与预期不符。经过近30分钟的调试、查阅资料及回顾视频,最终定位到问题根源。特此记录,以备后续查阅。核心问题在于判断素数时,对for...else语句结构的理解与使用不当(详见后续代码分析)。

素数判定逻辑与for-else陷阱

二、实现判断素数的功能

质数(Prime number),亦称素数,定义为大于1的自然数中,除了1和它本身以外不再有其他因数的数(即只有1与该数本身两个因数)。参考来源:Wikipedia。

基于此定义,可采用穷举法:若在2至n-1的区间内,没有任何数能整除n,则n为素数。

对2至n-1的区间进行合理优化。假设x*y=n且x<=y,当x与y相等时,x取得最大值,即x=y=sqrt(n)。因此,x的遍历区间可限制为2至sqrt(n)+1。若仍有疑问,建议通过纸笔演算进一步验证。

由于需要使用sqrt()函数,需导入math模块。

以下直接展示代码:


# 求解1000以内的所有素数,正确版本
import math

num = 2
count = 0
list_s = []
max_d = 1000
while num < max_d:
 length = int(math.sqrt(num)+1) # 对遍历范围进行合理优化
 for i in range(2,length): # 注意从2开始
  if num % i == 0:
   break
 else: # 这里的else跟for对齐,而不是跟if,表示只有for顺利执行时,else才执行
  count += 1
  list_s.append(num) # 存入列表
 num += 1
if count == 0:
 print(max_d,'以内没有素数')
else:
 print(max_d,'以内的素数有',count,'个,分别是:',list_s)

输出结果:

上述代码逻辑无误。接着提供一段存在问题的代码示例:


# 求解40以内的所有素数,错误版本
import math

num = 2
count = 0
list_s = []
max_d = 40
while num < max_d:
 length = int(math.sqrt(num)+1) # 对遍历范围进行合理优化
 for i in range(2,length): # 注意从2开始
  if num % i == 0:
   break
  else: # 这里的else跟if对齐,会导致一个素数会被写入int(math.sqrt(num))-1次,同时一些非素数也会被当做素数
   count += 1
   list_s.append(num) # 存入列表
 num += 1
if count == 0:
 print(max_d,'以内没有素数')
else:
 print(max_d,'以内的素数有',count,'个,分别是:',list_s)

输出结果:

因此,必须高度重视循环中else子句的对齐问题,这在解决素数判定问题时至关重要。以下总结while...else和for...else的行为机制。

仅当循环完整执行完所有迭代次数后,else子句才会执行。若循环体内存在continue语句,不影响else的执行。

一旦循环体内触发break语句,将阻止else子句块的执行。

回文数判定方法与双端队列优化

三、实现判断回文数的功能

回文数是指从左向右读取与从右向左读取完全相同的数字,例如:12321。

方法如下:

将已知数字num1反转得到num2(如123变为321)。通过//10和%10等运算操作,并借助临时变量tmp完成反转。

判断若num1等于num2,则num1为回文数;否则不是。

代码如下:


# 求解1000以内的所有回文数
num = 0 # 这里num从0开始
list_h = []
max_d = 10000
count = 0 

while num < max_d:
 tmp = num
 num_p = 0
 while tmp != 0:
  num_p = num_p*10 + tmp % 10
  tmp //= 10
 if num_p == num:
  list_h.append(num)
  count += 1
 num += 1
  
if count == 0:
 print(max_d,'以内没有回文数')
else:
 print(max_d,'以内的回文数有',count,'个,分别是:',list_h)

更新说明:对于判断回文数或回文字符串,使用双端队列(deque)数据结构可简化实现。具体代码如下:


from collections import deque

def palindrome(word):
 dq = deque(word)
 while len(dq) > 1:
  if dq.pop() != dq.popleft():
   return False
 return True

if __name__ == '__main__':
 max_num = 10000
 for i in range(max_num):
  s = str(i)
  if palindrome(s):
   print(i, end=',')

回文素数综合判定与性能对比

四、实现同时判断回文数和质数

需决定是否采用嵌套结构,以及先判断回文还是先判断素数,因此衍生出四个版本。读者可自行思考各版本在性能与空间占用上的差异。由于未深入分析,此处未列出详细对比。

我编写了四个版本,均能满足需求。但在100至1000000区间的测试中,采用嵌套结构且先求解回文数再判断素数的版本速度较快。

以下列出四个版本的完整代码,可自行移除相应的'''标记进行单独测试。


'''
# 版本一、求1000以内的回文素数,多层嵌套,先求素数后回文数

import math

num = 2
count = 0
list_s = []
list_sh = []
max_d = 1000
while num < max_d:
 length = int(math.sqrt(num)+1)
 for i in range(2,length):
  if num % i == 0:
   break
 else:
  list_s.append(num)
  tmp = num
  num_p = 0
  while tmp != 0:
   num_p = num_p * 10 + tmp % 10
   tmp //= 10
  if num == num_p:
   list_sh.append(num)
   count +=1
 num += 1
print(max_d,'以内的素数有:',list_s)
if count == 0:
 print(max_d,'以内没有既是素数又是回文数的数')
else:
 print(max_d,'以内既是素数又是回文数的数有',count,'个,分别是:',list_sh)

'''


'''
# 版本二、求1000以内的回文素数,多层嵌套,先求回文数后求素数

import math

num = 2
count = 0
list_h = []
list_hs = []
max_d = 1000
while num < max_d:
 tmp = num
 num_p = 0
 while tmp != 0:
  num_p = num_p * 10 + tmp % 10
  tmp //= 10
 if num == num_p:
  list_h.append(num)
  length = int(math.sqrt(num)+1)
  for i in range(2,length):
   if num % i == 0:
    break
  else:
   list_hs.append(num)
   count +=1
 num += 1
print(max_d,'以内的素数有:',list_h)
if count == 0:
 print(max_d,'以内没有既是素数又是回文数的数')
else:
 print(max_d,'以内既是素数又是回文数的数有',count,'个,分别是:',list_hs)
'''


'''
# 版本三、求1000以内的回文素数,先求素数再求回文数

import math

num = 2
list_s = []
max_d = 1000

while num < max_d:
 length = int(math.sqrt(num)+1)
 for i in range(2,length):
  if num % i == 0:
   break
 else: # 注意这里的else是和for对齐
  list_s.append(num)
 num += 1


count = 0
list_sh = []
for i in list_s:
 tmp = i
 num_p = 0
 while tmp != 0:
  num_p = num_p*10 + tmp % 10
  tmp //= 10
 if num_p == i:
  list_sh.append(i)
  count += 1
  

print(max_d,'以内的素数有:',list_s)
if count == 0:
 print(max_d,'以内没有既是素数又是回文数的数')
else:
 print(max_d,'以内既是素数又是回文数的数有',count,'个,分别是:',list_sh)
'''


'''
# 版本四、求1000以内的回文素数,先求回文数,再求素数

import math

num = 2
list_h = []
max_d = 10000

while num < max_d:
 tmp = num
 num_p = 0
 while tmp != 0:
  num_p = num_p*10 + tmp % 10
  tmp //= 10
 if num_p == num:
  list_h.append(num)
 num += 1


count = 0
list_sh = []
for hn in list_h:
 length = int(math.sqrt(hn)+1)
 for i in range(2,length):
  if hn % i == 0:
   break
 else: # 注意这里的else是和for对齐
  list_sh.append(hn)
  count += 1
  

print(max_d,'以内的回文数有:',list_h)
if count == 0:
 print(max_d,'以内没有既是素数又是回文数的数')
else:
 print(max_d,'以内既是素数又是回文数的数有',count,'个,分别是:',list_sh)
'''

总结:语法结构深度理解

五、总结

此过程加深了对if...elif...else、for...else及while...else结构的理解,未来使用时将更加谨慎。

以上关于解决Python中回文数和质数问题的内容即为分享全部,希望能提供参考,并欢迎大家支持本站。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表