当前位置:首页>python>跟着NOAI考纲学Python,学完就能考,第14课

跟着NOAI考纲学Python,学完就能考,第14课

  • 2026-10-01 22:14:07
跟着NOAI考纲学Python,学完就能考,第14课

每天一个知识点,带你自学NOAI,加入我们吧~

上节课学了排序,把数据排整齐。排整齐之后干什么?当然是找东西。这节课学两种查找方法——线性查找和二分查找。学完这节,NOAI考纲里Python基础部分的知识点就全部覆盖了。

线性查找

最简单的查找方法:从第一个开始,一个一个往后看,看到目标就停。

deflinear_search(lst, target):foriinrange(len(lst)):iflst[i] == target:returnireturn -1nums = [4, 2, 7, 1, 9, 3]print(linear_search(nums, 7))   # 找到了,在位置2print(linear_search(nums, 5))   # 没找到,返回-1

2-1

逻辑很直白:遍历整个列表,找到目标就返回它的索引,全部看完都没找到就返回 -1。不管列表有没有排过序,线性查找都能用。

线性查找就像翻书一页一页找——从第一页翻到最后一页。二分查找就像查字典——翻到中间看一眼,要找的字在前面就翻前半本,在后面就翻后半本。每翻一次就排除一半。

用 in 判断

Python有更简单的写法:

nums = [4, 2, 7, 1, 9, 3]print(7innums)     # 在不在?print(nums.index(7))  # 在第几个位置?

True2

方便,但有局限:

•in 只告诉你在不在,不告诉你在哪

•.index() 能告诉你位置,但如果元素不存在会直接报错,不像我们写的函数那样返回 -1

所以实际开发中通常先用 in 判断存不存在,再用 .index() 取位置。但考试考的是查找算法的原理,所以手写查找函数你得会。

二分查找

线性查找简单但慢——要一个一个看。如果列表已经排好序了,可以用更快的方法:二分查找。

思路:先看中间的数。如果目标比中间的小,就去左半边找;如果比中间的大,就去右半边找。每一步都把范围砍一半。

defbinary_search(lst, target):left = 0right = len(lst) - 1whileleft <= right:mid = (left + right) // 2iflst[mid] == target:returnmideliflst[mid] < target:left = mid + 1else:right = mid - 1return -1nums = [1, 3, 5, 7, 9, 11, 13]print(binary_search(nums, 7))    # 3print(binary_search(nums, 6))    # -1

3-1

找 7 的过程

列表是 [1, 3, 5, 7, 9, 11, 13],找 7:

• left=0, right=6, mid=3, lst[3]=7,正好等于目标,直接返回 3

一步就找到了。

找 6 的过程

• left=0, right=6, mid=3, lst[3]=7 > 6,目标在左边,right=2

• left=0, right=2, mid=1, lst[1]=3 < 6,目标在右边,left=2

• left=2, right=2, mid=2, lst[2]=5 < 6,目标在右边,left=3

• left=3 > right=2,循环结束,返回 -1

7个数,3步就确定找不到了。

二分查找有多快

具体比较一下:

• 1000个数据,线性查找最多找 1000 次

• 1000个数据,二分查找最多找 10 次(因为 2的10次方 = 1024 > 1000)

• 100万个数据,线性查找最多 100万 次,二分查找最多 20 次

差距非常大。这就是为什么"先排序再二分查找"是很多算法的基础操作。

但要注意:二分查找只能用在已经排好序的列表上。如果列表是乱序的,要么先排序再二分,要么直接用线性查找。

实战:排序 + 查找

把上节课和这节课学的组合起来——先排序,再二分查找:

defbinary_search(lst, target):left = 0right = len(lst) - 1whileleft <= right:mid = (left + right) // 2iflst[mid] == target:returnmideliflst[mid] < target:left = mid + 1else:right = mid - 1return -1scores = [78, 92, 55, 88, 41, 67, 95]scores.sort()  # 先排序print("排好序:", scores)pos = binary_search(scores, 88)ifpos != -1:print("88分在位置", pos)else:print("没找到88分")

排好序: [41, 55, 67, 78, 88, 92, 95]88分在位置 4

这就是排序和查找的经典组合:先用 .sort() 排好序,再用二分查找快速定位。

易错点

错误1二分查找忘了排序

二分查找只在排好序的列表上才有效。对一个乱序列表用二分查找,结果完全不可靠:

nums = [9, 3, 7, 1, 5]  # 没排序!print(binary_search(nums, 3))  # 结果可能是错的

用二分查找之前,先确认列表已经排好序。

错误2mid 的计算用 / 不用 //

mid = (left + right) / 2# 错!得到3.0,浮点数不能当索引mid = (left + right) // 2# 对!得到3,整数才能当索引

/ 是普通除法,结果是浮点数;// 是整除,结果是整数。列表索引必须是整数,所以必须用 //。

动手试试

自己先想,想完了去香农平台上写代码跑一遍验证。

练习1:预测输出

列表 [2, 5, 8, 12, 16, 23, 38, 56, 72, 91],用二分查找找 23。写出每一步 left、right、mid 的值,最终返回什么?

提示:第一步 left=0, right=9, mid=4,lst[4]=16 < 23,所以 left=5...

练习2:找bug

小明对一个乱序列表直接用二分查找,发现明明有的数字却返回 -1。问题出在哪?怎么修?

nums = [8, 3, 5, 1, 9, 2]print(binary_search(nums, 5))

提示:二分查找的前提条件是什么?

练习3:写代码

给你一个列表 nums = [45, 12, 78, 34, 56, 23, 89, 67] 和一个目标值 target = 56。先把列表排序,再用二分查找找到目标值的位置,打印结果。

提示:先 sort(),再调用 binary_search(),最后打印。

去平台上手写代码

查找是算法入门的核心知识点。回顾一下:

•线性查找 — 逐个比较,简单但慢

•二分查找 — 每次排除一半,快但必须先排序

•in 和 index() — Python的查找捷径

• 1000个数据线性查 1000 次,二分只查 10 次

这篇文章讲的是香农NOAI学习平台"Python基础"模块的第十四课。平台上有更多的练习题,写完代码点运行,对不对立刻就知道。

香农NOAI学习平台地址:shannon.arpa.school微信扫码登录就能用,免费。找到「Python基础」→「查找」,从第一道题开始写。

到这里,NOAI考纲里Python基础部分的知识点全部讲完了。从第一行 print 到现在的二分查找,14节课覆盖了:变量、数据类型、输入输出、条件判断、循环、列表、函数、字典、元组、字符串、模块、排序、查找。

接下来的课程会进入数据处理和AI——用NumPy、Pandas处理数据,用Matplotlib画图,这些是NOAI考试第二轮的核心内容。

IOI2026国家队选拔第一名的他,IOAI国际人工智能奥赛也拿到了银牌
当年的IOI中国国家队成员,20年后过得怎么样?
IOAI人工智能奥赛获奖选手,被哪些世界顶尖大学抢走了?
NOAI人工智能奥赛与5大奥赛齐名,却不在白名单,还值得孩子花时间吗?
数学和信息学双料奥赛金牌邓明扬,最近一篇顶会论文让AI圈炸了
我们从2018年开始关注青少年AI竞赛
见证了NOAI从无到有
这里为你拆解这个赛事的每一个关键问题
欢迎关注公众号~
👇NOAI复赛集训开始招募
👇加入NOAI学习交流群
👆消除信息壁垒、少走弯路
👆获取往届真题、比赛资源
👆链接牛娃家长、抱团互助

最新文章

随机文章