各位未来的IT精英们好~ 今天带来一个Python入门必练的经典案例——输出指定范围内的质数,适合零基础新手打基础,也适合有一定基础的同学巩固逻辑、优化代码。
很多新手刚接触循环、条件判断时,都会被“质数判断”难住:到底怎么判断一个数是不是质数?为什么要双重循环?有没有更高效的写法?
这篇教程会从「概念拆解→基础实现→代码逐行精讲→常见误区→多版本优化→实战拓展」,一步步带你吃透这个练手项目,代码可直接复制运行,看完就能上手,收藏起来慢慢练!
一、先吃透:什么是质数?(新手必懂)
在开始写代码前,我们必须先明确核心概念——质数(也叫素数),很多新手出错,都是因为对概念理解不透彻。
质数的严格定义:大于1的正整数,除了1和它本身之外,没有其他正因数(也就是说,不能被任何其他自然数整除)。
拆解2个关键要点,避免踩坑:
- 关键点1:必须大于1——所以1不是质数,2是最小的质数,也是唯一的偶数质数(重点记!很多新手会把1当成质数,把2排除在外);
- 关键点2:只有两个正因数——1和它本身,比如7,只能被1和7整除,所以是质数;而8能被2、4整除,就不是质数。
举几个直观例子,帮大家区分:
✅ 质数:2、3、5、7、11、13、17、19(除了1和自身,无其他因数);
❌ 非质数:1(不大于1)、4(能被2整除)、6(能被2、3整除)、9(能被3整除)、10(能被2、5整除)。
二、明确需求:我们要实现什么?
本次练手目标(兼顾基础和实用性):
- 输出2~100之间的所有质数(新手入门首选范围,数据量适中,易验证结果);
- 从基础版到优化版,逐步提升代码效率,理解“优化”的核心思路;
- 能灵活修改代码,适配不同范围(比如100~200、1~500的质数)。
三、基础版实现:新手能直接复制运行(逻辑最易懂)
先从最基础的版本入手,核心逻辑是“逐一验证”——遍历每个数字,判断它是否能被除了1和自身之外的数整除,适合完全零基础的同学理解循环和条件判断的用法。
# 基础版:输出2~100之间的所有质数
# 核心逻辑:遍历每个数字,逐一验证是否为质数
# 1. 遍历2到100的所有数字(range左闭右开,所以写101)
for num in range(2, 101):
# 2. 先假设当前数字是质数,用布尔值标记(初始值为True)
is_prime = True
# 3. 验证:用2到num-1的所有数字,试除当前数字num
# 为什么是2到num-1?因为质数只能被1和自身整除,排除这两个数
for i in range(2, num):
# 若num能被i整除(余数为0),说明不是质数
if num % i == 0:
is_prime = False# 标记为非质数
break# 无需继续验证,直接跳出内层循环(节省时间)
# 4. 若最终is_prime仍为True,说明是质数,打印输出
if is_prime:
print(num, end=" ") # end=" " 让结果横向排列,更美观
四、逐行精讲:吃透每一行代码(新手必看)
很多新手复制代码能运行,但不知道为什么这么写,这里逐行拆解,帮你把逻辑刻在脑子里,以后遇到类似问题能举一反三。
1. 外层循环:遍历需要验证的数字
for num in range(2, 101):
- range(2, 101) 表示生成2到100的所有整数(左闭右开,所以结束值要写101,才能包含100);
- num 是循环变量,每次循环都会取一个数字,从2开始,直到100结束,我们要做的就是判断每个num是不是质数。
2. 质数标记:用布尔值记录状态
is_prime = True
- 这是新手最容易忽略的一步:先“假设”当前数字是质数(标记为True),再通过后续验证推翻这个假设;
- 为什么不先假设为False?因为质数的判断是“排除法”——只要找到一个能整除它的数,就不是质数;如果找不到,就是质数,先设为True更符合逻辑。
3. 内层循环:验证是否为质数
for i in range(2, num):
- 内层循环的作用是“试除”:用2到num-1的所有数字,去整除当前的num;
- 为什么不从1开始?因为1能整除所有数字,没有意义;为什么到num-1结束?因为num本身肯定能整除自己,无需验证。
4. 条件判断:推翻“质数假设”
if num % i == 0:
- % 是Python中的“取余运算符”,num % i == 0 表示“num能被i整除”;
- 一旦找到一个i能整除num,就说明num不是质数,此时把is_prime改为False,并且用break跳出内层循环——因为已经确定不是质数,再继续试除其他数字没有意义,能节省运行时间。
5. 输出结果:打印所有质数
if is_prime: print(num, end=" ")
- 循环结束后,若is_prime仍为True,说明没有找到能整除num的数,num就是质数;
- end=" " 是print函数的参数,默认情况下print会自动换行,加上这个参数后,会用两个空格分隔每个质数,横向排列,看起来更整洁。
五、运行效果验证(新手必做)
把上面的基础版代码复制到Python编辑器(IDLE、PyCharm、VS Code都可以),运行后会得到以下结果:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
大家可以手动核对一下:2是最小的质数,97是100以内最大的质数,中间的数字都是符合质数定义的,说明代码运行正常。
六、新手常见误区(避坑指南)
很多新手写这段代码时,会出现各种小错误,导致结果不对,这里整理了4个最常见的误区,帮你避开坑:
误区1:把1当成质数
错误写法:外层循环从1开始(range(1, 101)),导致1被当成质数输出;
正确做法:外层循环从2开始(range(2, 101)),因为1不满足“大于1”的质数条件。
误区2:内层循环范围写错
错误写法:内层循环写成range(2, num+1),导致num被自己整除,所有数字都被判断为非质数;
正确做法:内层循环写成range(2, num),排除num本身。
误区3:忘记写break
错误写法:找到能整除num的i后,不写break,继续循环;
影响:不影响最终结果,但会增加不必要的循环次数,代码效率变低(比如判断4时,找到2能整除4,还会继续判断3,浪费时间)。
误区4:偶数质数的判断遗漏
错误写法:手动排除2,导致2没有被输出;
注意:2是唯一的偶数质数,代码中无需手动排除,基础版代码会自动判断2是质数(因为内层循环range(2, 2)是空的,不会执行,is_prime一直是True,会被打印)。
七、进阶优化:3个版本,提升代码效率(进阶必学)
基础版代码逻辑易懂,但效率不高——比如判断97是不是质数时,需要从2循环到96,做94次判断,其实有更高效的方法。下面分享3个优化版本,从简单到复杂,帮你理解“代码优化”的思路。
优化版1:排除所有偶数(最易实现)
核心思路:除了2之外,所有偶数都不是质数,所以可以先单独输出2,然后只遍历奇数,减少一半的循环次数。
# 优化版1:排除偶数,减少循环次数
print(2, end=" ") # 单独输出唯一的偶数质数
# 只遍历奇数(从3开始,步长为2,避免遍历偶数)
for num in range(3, 101, 2):
is_prime = True
# 内层循环也可以只遍历奇数(进一步优化)
for i in range(3, num, 2):
if num % i == 0:
is_prime = False
break
if is_prime:
print(num, end=" ")
优化效果:外层循环从50次(2~100)减少到49次(3~99的奇数),内层循环也减少一半次数,运行速度明显提升。
优化版2:循环到平方根(效率大幅提升)
核心原理:一个数如果有因数,那么它的两个因数中,一定有一个不大于它的平方根。比如16的平方根是4,它的因数是2和8,2≤4;9的平方根是3,因数是3和3,3≤3。
所以,我们不需要遍历到num-1,只需要遍历到num的平方根,就能判断是否为质数,大幅减少循环次数(比如判断97,平方根约为9.8,只需要遍历到9,比遍历到96节省太多时间)。
# 优化版2:循环到平方根,效率大幅提升
import math # 导入math模块,用于计算平方根
for num in range(2, 101):
is_prime = True
# 计算num的平方根,转换为整数(range需要整数参数)
sqrt_num = int(math.sqrt(num))
# 内层循环只需要到sqrt_num
for i in range(2, sqrt_num + 1):
if num % i == 0:
is_prime = False
break
if is_prime:
print(num, end=" ")
注意:math.sqrt(num)返回的是浮点数(比如sqrt(97)=9.849...),所以需要用int()转换为整数,并且要加1(因为range左闭右开,比如sqrt_num=9,range(2, 10)才能包含9)。
优化版3:结合前两种优化(最优版本)
把“排除偶数”和“循环到平方根”结合起来,是效率最高的写法,适合处理大范围的数字(比如1~10000、1~100000的质数)。
# 优化版3:结合排除偶数+循环到平方根(最优)
import math
print(2, end=" ")
# 外层遍历奇数
for num in range(3, 101, 2):
is_prime = True
sqrt_num = int(math.sqrt(num))
# 内层也遍历奇数
for i in range(3, sqrt_num + 1, 2):
if num % i == 0:
is_prime = False
break
if is_prime:
print(num, end=" ")
对比基础版:判断100以内的质数,基础版需要执行上千次循环,而这个版本只需要几十次,效率提升非常明显。
八、实战拓展:修改代码,适配不同需求
学会了基础版和优化版,我们可以灵活修改代码,实现不同的需求,新手可以试着练习以下3个拓展任务,巩固知识点:
拓展任务1:输出100~200之间的质数
修改点:只需要把外层循环的range范围改成(100, 201),其他代码不变(推荐用优化版3,效率更高)。
拓展任务2:统计2~100之间质数的个数
修改点:增加一个计数器变量(比如count = 0),每次判断出质数时,count += 1,最后打印count即可。
# 拓展:统计2~100之间质数的个数
import math
count = 0# 计数器,初始值为0
for num in range(2, 101):
is_prime = True
sqrt_num = int(math.sqrt(num))
for i in range(2, sqrt_num + 1):
if num % i == 0:
is_prime = False
break
if is_prime:
count += 1# 找到质数,计数器加1
print(f"2~100之间的质数共有:{count}个") # 输出结果:25个
拓展任务3:让用户输入范围,输出该范围内的质数
修改点:用input()函数获取用户输入的起始值和结束值,转换为整数后,作为range的参数。
# 拓展:用户输入范围,输出该范围内的质数
import math
# 获取用户输入,转换为整数
start = int(input("请输入起始数字:"))
end = int(input("请输入结束数字:"))
# 处理起始值小于2的情况(确保从2开始)
if start < 2:
start = 2
# 输出该范围内的质数
print(f"{start}~{end}之间的质数:", end="")
for num in range(start, end + 1):
is_prime = True
sqrt_num = int(math.sqrt(num))
for i in range(2, sqrt_num + 1):
if num % i == 0:
is_prime = False
break
if is_prime:
print(num, end=" ")
九、总结:新手必掌握的核心要点
通过这个“输出质数”的练手项目,我们主要掌握了以下3个核心知识点,这些知识点在后续的Python学习中会经常用到:
- 双重循环的用法:外层循环遍历数据,内层循环做验证(核心逻辑);
- 布尔值的应用:用True/False标记状态,实现“假设-验证”的逻辑;
- 代码优化思路:从“减少循环次数”入手,逐步提升代码效率(排除偶数、循环到平方根)。
最后提醒大家:新手学习Python,不要只复制代码,一定要逐行理解逻辑,试着自己修改代码、完成拓展任务,这样才能真正掌握知识点。
如果运行代码时遇到问题,或者有其他优化思路,欢迎在评论区留言交流~ 关注我,每天一个Python练手小案例,新手也能快速入门!