Python函数编程核心:作用域、递归与算法实战解析

发布时间:2026/10/24 12:49:09

Python函数编程核心:作用域、递归与算法实战解析 简介本资源为《Python编程实践》第8章练习题及解答的PDF文档作者陈波、刘慧君面向正在学习Python基础语法与函数式编程的初学者及高校学生帮助其通过配套习题巩固课堂知识、检验掌握程度。压缩包内仅含1个PDF文件大小约224KB轻量便携适合在电脑或移动设备上随时查阅。内容覆盖函数编程、递归、循环、字符串处理、数字转换、回文素数等多个主题具体包括整数各位数字之和、递归求和、十进制转十六进制/八进制/二进制、不特定多参数乘积、前100个回文素数打印以及折半查找等典型题目。每道题均给出答案与思路解析并附示例代码便于读者对照理解函数参数传递、递归调用、取模运算与素数筛选等关键知识点。目前已有1935人学习下载可作为课后自测与期末复习的实用参考。1. 变量作用域到底是怎么回事从一个“同名不同命”的困惑说起很多人第一次学 Python 函数时都遇到过这样的怪事函数里面写了一个x 77函数外面也有一个x 1调用完函数再打印外面的x它居然还是 1。明明函数里改了呀这就像你在自己家冰箱里放了一瓶可乐邻居家冰箱里也有一瓶你打开邻居家冰箱把可乐换成了雪碧回到自己家打开冰箱——可乐还在。两瓶可乐同名但住在不同的“作用域”里互不干扰。这个“同名不同命”的现象就是 Python 变量作用域最直观的体现。搞懂它你才能明白为什么有些变量函数里能用、外面不能用为什么有些函数改完值外面却“看不见”。而这份《Python编程实践》第 8 章的练习题及解答恰好把作用域、递归、进制转换、回文素数、折半查找这些函数编程的核心概念串成了一条线。它不是干巴巴地讲语法而是用一道道题逼你把“函数到底怎么跑”想清楚。接下来我们就把这些概念一个个拆开用大白话讲透。2. 函数编程的底层逻辑为什么变量会“认生”2.1 局部变量与全局变量函数里的“优先权”规则先看一个典型场景。假设有这样一个程序x 1 y 1 def func(): x 77 z y * 2 print(xy, x z) func() print(x, x) print(y, y)运行结果是xy 79然后x 1y 1。为什么函数里的x变成了 77外面的x还是 1因为 Python 在函数内部遇到赋值语句x 77时会认为x是一个局部变量它只在函数执行期间存在函数一结束就消失了。而y在函数里没有被赋值Python 就会去全局作用域找找到了外面的y 1所以z 1 * 2 2最终x z 77 2 79。通俗地说函数就像一个房间里面可以放自己的东西局部变量也可以借用外面的东西全局变量但如果你在房间里放了一个和外面同名的东西房间里的人就只认自己那个外面的完全不受影响。这就是“局部优先”原则。注意如果你在函数里只是想读取全局变量不赋值那没问题一旦赋值Python 就默认你要创建一个新的局部变量除非你用global声明。2.2 递归函数自己调用自己的“套娃”艺术第 8 章里有一道题要求计算f(i) 1/2 2/3 3/4 … i/(i1)还有一道题用递归求1 到 9 的奇数和。递归听起来玄乎其实就是函数自己调用自己把一个大问题拆成一个小一号的同类问题直到拆到最简单的情况直接给出答案。比如求奇数和def func(x): if x 1: return 1 return x func(x - 2) print(func(9))执行过程是这样的func(9)发现 9 大于 1于是返回9 func(7)func(7)又返回7 func(5)……一路拆到func(1)它直接返回 1。然后一层层往回加1 3 5 7 9 25。这就像你有一摞盘子每次拿掉两个直到只剩一个再把拿掉的盘子数加起来。递归的关键在于终止条件。没有if x 1: return 1这一句函数就会无限调用自己直到程序崩溃。所以写递归时第一件事就是想清楚什么时候停下来2.3 不定参数一个函数怎么吃下“不特定多个数”第 8 章还有一道题要求“计算一个或不特定多个数的乘积”。Python 用*temp这种写法来接收任意数量的参数def caculate(*temp): ans 1 for x in temp: ans * x return ans print(caculate(1, 2, 3, 4, 5))这里的*temp会把传入的所有参数打包成一个元组函数内部就可以像遍历列表一样遍历它。你传 3 个数temp就是(1, 2, 3)传 5 个数就是(1, 2, 3, 4, 5)。这就像你去自助餐厅拿一个盘子想装几样菜就装几样厨师函数只管把你盘子里的菜全炒了。这种写法在实际开发中很常见比如日志函数要接收任意数量的消息片段或者数学计算函数要接收任意多个操作数。它让函数的接口变得灵活不用提前规定“你必须传 3 个参数”。3. 数字转换与回文素数两个经典练习背后的思维训练3.1 进制转换为什么“除 R 取余、反序输出”能行第 8 章要求写三个函数分别把整数转成十六进制、八进制、二进制字符串。核心方法就一句话不断用 n 除以 R取余数直到 n 为 0最后把余数反着拼起来。以十进制转二进制为例假设 n 1313 % 2 1n 变成 66 % 2 0n 变成 33 % 2 1n 变成 11 % 2 1n 变成 0余数依次是 1、0、1、1反序就是 1101正好是 13 的二进制。为什么反序因为第一次算出来的是最低位最后算出来的是最高位就像你读数字是从左往右读但计算时是从右往左拆的。十六进制稍微麻烦一点因为 10 到 15 要用 A 到 F 表示。代码里用一个字典做映射Map {0:0, 1:1, ..., 10:A, 11:B, 12:C, 13:D, 14:E, 15:F}每次取余后查字典最后同样反序。这个思路不仅适用于 2、8、16 进制换成任意进制 R 都成立只要处理好大于 9 的数字怎么表示就行。3.2 回文素数两个判断条件怎么优雅地合在一起回文素数是指一个数既是素数又是回文数比如 131。第 8 章要求打印前 100 个回文素数每行 10 个。这道题把两个独立的知识点揉在了一起素数判断和回文判断。素数判断用的是筛选法从 2 开始把每个素数的倍数都标记为“非素数”剩下的就是素数。代码里用了一个字典count来记录被筛掉的数prime [] count {} for i in range(2, 100000): temp i if temp not in count: prime.append(temp) while temp 100000: count[temp] 1 temp i回文判断则是把数字转成字符串然后比较首尾字符是否对称def judge(temp): value_str str(temp) Len len(value_str) for i in range(Len // 2): if value_str[i] ! value_str[Len - 1 - i]: return False return True最后遍历素数列表用judge过滤出回文数凑够 100 个就停。这道题的价值在于它让你练习了把两个小功能组合成一个大功能而且每个小功能都写成独立的函数逻辑清晰改起来也方便。3.3 折半查找为什么“砍一半”能这么快折半查找也叫二分查找是第 8 章另一个重点。题目给了一个已按学号排序的学生列表要求用折半查找找到指定学号。核心思想是每次拿中间位置的元素和目标比较如果目标比中间小就去左半边找比中间大就去右半边找相等就找到了。def Binary_Find(Stu): bottom 0 top len(Stu) - 1 while bottom top: mid (bottom top) // 2 if num int(Stu[mid][0]): return 已找到 elif num int(Stu[mid][0]): bottom mid 1 elif num int(Stu[mid][0]): top mid - 1 return 没有找到为什么快因为每次比较都能把查找范围缩小一半。20 个学生最多比较 5 次就能确定有没有1000 个学生最多 10 次。这就像你猜一个 1 到 100 之间的数字每次猜中间值最多 7 次就能猜中。折半查找的前提是数据必须有序如果列表是乱序的这个方法就失效了。4. 常见误区与易混概念这些坑你踩过几个4.1 局部变量和全局变量同名时到底用哪个易混点函数里写x 77外面也有x 1函数里打印x是 77外面打印还是 1。很多人以为函数里的赋值会“覆盖”外面的。为什么混因为其他语言比如 C里函数内外的同名变量可能通过指针或引用互相影响但 Python 的赋值是“创建新名字”不是“修改原名字”。怎么区分记住一句话——函数内赋值即局部除非用global声明。如果你真的想在函数里修改全局变量得写global x然后x 77这样外面的x才会变。4.2 递归和循环什么时候非得用递归易混点求奇数和既可以用递归也可以用循环那为什么还要学递归为什么混因为很多问题用循环也能解决初学者觉得递归多此一举。怎么区分递归适合问题本身是嵌套结构的场景比如“分治法找假硬币”——把一堆硬币分成两半称一称假币在哪边就继续分哪边。这种“大问题拆成同类小问题”的逻辑用递归写出来几乎和自然语言一样直白。循环适合“重复做同一件事直到满足条件”比如遍历列表、累加求和。简单说结构嵌套用递归线性重复用循环。4.3 进制转换时为什么余数要反序易混点算出来的余数直接拼起来不行吗为什么非要反序为什么混因为第一次算出的余数是最低位但人读数字是从最高位读的。怎么区分拿 13 转二进制举例余数依次是 1、0、1、1如果直接拼是 1011但 1011 是 11不是 13。反序后 1101 才是 13。记住先算出来的是低位后算出来的是高位输出时要倒过来。4.4 折半查找为什么要求数据有序易混点折半查找看起来只是“每次取中间”跟数据有没有排序有什么关系为什么混因为代码里只写了比较中间值没写排序容易忽略前提。怎么区分折半查找的逻辑是“目标比中间小就去左边比中间大就去右边”这个判断成立的前提是左边所有数都比中间小右边所有数都比中间大。如果数据没排序左边可能藏着比中间大的数你的判断就错了。所以用折半查找之前必须先排序。4.5 不定参数*temp和普通参数混用时顺序怎么排易混点def func(a, *temp)和def func(*temp, a)有什么区别为什么混因为*temp看起来像个普通参数实际上它会把后面所有位置参数都吃掉。怎么区分*temp必须放在普通位置参数后面。def func(a, *temp)表示第一个参数给a剩下的全给tempdef func(*temp, a)在 Python 3 里表示a必须用关键字传参比如func(1, 2, a3)。初学阶段记住普通参数在前*temp在后就不会出错。5. 什么时候该翻出这份练习题一个“卡住时”的用法示例学 Python 函数编程最怕的不是看不懂语法而是看懂了却写不出来。这份第 8 章练习题及解答的价值恰恰在于它把“写不出来”的瞬间提前暴露给你。比如你觉得自己会递归了但让你写一个“用递归求 1 到 9 的奇数和”你可能卡在终止条件上你觉得自己会进制转换了但让你处理十六进制的 A 到 F你可能忘了做映射。那什么时候该用它我的经验是当你学完函数、递归、循环这几章感觉自己“好像会了”的时候直接翻到这份题盖住答案自己先写一遍。写不出来说明你只是“看懂了”没真正掌握写出来了但和答案不一样对比一下思路往往能发现更简洁的写法。比如回文素数那道题答案用了筛选法先把素数全找出来再过滤回文数比“逐个判断是不是素数、是不是回文”效率高得多。这种“先批量筛选、再条件过滤”的思路在以后处理大数据时非常有用。但也要注意这份题不是万能的。它偏重函数编程的基础训练不涉及面向对象、文件操作、异常处理这些后续章节的内容。如果你已经能熟练写出递归、进制转换、折半查找那这份题对你来说就偏简单了可以直接跳过去练更复杂的项目。另外题目里的代码风格偏“教学版”比如变量名用temp、ans实际开发中建议用更有意义的名字比如remainder、total。提示做题时不要只看答案的“思路”部分一定要自己动手敲一遍。很多坑比如递归忘记写终止条件、折半查找忘记排序只有亲手写才会踩到。从那以后我每次带人学 Python 函数都强制让他们先自己做一遍第 8 章的题做完再对照答案。因为“看会”和“写会”之间隔着一条河而练习题就是那座桥。希望这份资料能帮你顺利过河。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/10/24 12:49:09

Python爱心粒子动画代码拆解:pygame粒子系统与贝塞尔曲线实现

简介:这是一份基于Python实现爱心粒子动态效果的代码详解文档,适合Python入门者、趣味编程爱好者及需要图形动画参考的开发者使用。资源以单个docx文档形式打包,压缩后大小仅39KB,内容完整且便于快速下载。文档系统梳理了从环境准…

2026/10/24 12:49:09

Java反射原理与实战:从Class对象到动态代理的完整指南

简介:针对Java面试中高频的反射机制专题,这份PDF整理汇总了11道经典面试题及解答,适合正在准备Java后端岗位面试、希望系统梳理反射知识点的开发者阅读。内容涵盖new与反射创建对象的效率差异、反射在JDBC/Hibernate/Spring等框架中的应用、获…

2026/10/24 12:49:09

TD-LTE RLC协议详解:从快递比喻到ARQ重传机制

简介:这份资源是面向TD-LTE无线接入网研发、协议栈实现与测试人员的RLC协议中文技术文档,对应《TD-LTE数字蜂窝移动通信网Uu接口技术要求》第7部分,由中国通信标准化协会组织制定。内容围绕E-UTRA RLC子层展开,涵盖RLC实体结构、上…

2026/10/24 13:44:14

充电宝工厂MES系统实施与生产追溯方案

1. 为什么充电宝工厂需要MES系统?去年参观深圳某充电宝代工厂时,看到质检员正在用Excel手工记录不良品数据,产线主管每周要花两天时间整理生产报表。这种场景在中小型制造企业太常见了——工序靠纸单传递、质量靠人工抽检、追溯靠翻查记录本。…

2026/10/24 13:44:14

Aurora 8B/10B IP核详解:GTX引脚选型与高速串口仿真排障实战

简介:这是一份针对Xilinx Aurora 8B/10B IP核的详解与仿真指南,面向FPGA开发及高速串行通信工程师。内容在解析官方文档基础上,重点梳理IP核配置流程、8B/10B编码原理、GTX引脚选择与约束方法,并补充仿真测试平台搭建、源码与约束…

2026/10/24 13:44:14

ChatGPT本质是知识调用方式升级:预训练、RLHF与工程实践全解析

简介:这份资源是哈尔滨工业大学自然语言处理研究所于2023年3月6日发布的ChatGPT调研报告,共94页,面向AI从业者、研究者及对大模型技术感兴趣的学习者,帮助系统理解ChatGPT的技术脉络与产业影响。报告由多位师生共同撰写&#xff0…

2026/10/24 13:44:14

VMD信号分解与重构技术在故障诊断中的应用

1. 信号处理中的模态分解与重构技术解析在工业监测、生物医学和机械故障诊断等领域,我们经常需要从复杂的混合信号中提取有效成分。传统傅里叶变换在处理非平稳信号时存在明显局限,而基于变分模态分解(VMD)的方法通过自适应分解机制,能够将原…

2026/10/24 13:44:14

AI测试助手如何提升系统运维效率与故障预警

1. 为什么系统工程师需要AI测试助手?在传统IT运维和系统管理工作中,工程师们常常被海量的日志分析、性能监控和故障排查所困扰。我曾经历过一次线上事故:凌晨三点被报警电话惊醒,面对数百台服务器产生的GB级日志,手动排…

2026/10/24 13:39:14

从JDBC到自研ORM:反射与注解构建可复用数据访问层

简介:一份面向Java开发者的PDF教程,聚焦利用Spring JDBC的设计理念手写定制ORM框架,适合有一定基础、想深入理解持久层原理的工程师,也适合为后续学习MyBatis做铺垫。教程从原生JDBC的典型操作入手,逐步拆解加载驱动、…

2026/10/23 22:56:35

金融AI落地指南:从调研报告到技术选型与工程实践

简介:这份PDF报告聚焦2025年金融服务业中国AI现状与趋势,面向金融科技从业者、AI战略规划人员及关注行业数字化转型的研究者,帮助读者把握生成式AI在银行、支付、交易等场景中的落地路径与投资方向。资源包内含1个PDF文件,大小约1…

2026/10/24 0:02:40

MATLAB缩进快捷键与批量格式化实战指南

1. 被自动缩进折磨的那些年如果你写过MATLAB代码,大概率经历过这种场景:从某个文档、网页或者聊天记录里复制了一段代码,粘贴进编辑器之后,每一行前面都带着莫名其妙的空格,有的行首是四个空格,有的是一个T…

2026/10/24 0:02:40

用Poco实现Qt风格信号与槽的跨平台C++方案

简介:本资源是一份面向C中级开发者的技术实践工程,聚焦于在非Qt框架环境下模拟实现Qt核心通信机制——信号与槽,借助Poco网络库的事件系统完成解耦式对象通信。适用于需在跨平台C项目中引入松耦合回调机制、但受限于无法集成Qt依赖的开发场景…

2026/10/24 0:02:40

ESXi裸机虚拟化安装指南:从硬件兼容到虚拟机部署

1. 为什么还要折腾ESXi:从一台闲置机器说起手里攒了几台淘汰下来的迷你主机,配置不算差,i5加16G内存,扔了可惜,装个桌面系统又觉得浪费。这种场景下,ESXi就成了一个绕不开的选择。它是一套裸机虚拟化平台&a…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑