很多自学Python的人,可能都经历过一个比较相似的阶段。
网盘中保存了几十GB的课程资料,编程书籍也买了不少,每天跟着视频输入代码。观看课程时感觉知识点都能听懂,示例项目复制下来以后,也可以正常运行。
但是,一旦离开教程,需要自己编写一个小脚本,或者解决某个实际问题时,往往就不知道应该从哪里开始。
投入了不少时间,实际编程能力却没有出现明显提升,问题可能并不在于课程数量不够,而是学习过程中缺少独立分析和解决问题的训练。
编程本质上是使用代码处理具体问题。
能够看懂别人写的代码,并不代表自己能够独立完成代码。想要逐渐建立编程思维,除了学习语法和观看案例,还需要通过练习题不断训练需求分析、代码实现以及错误排查能力。
这套150道Python练习题,可以按照三个阶段开展练习:
基础50题、进阶50题和算法实战50题。
内容从Python基础语法开始,逐渐延伸到文件处理、自动化脚本以及常见算法问题。完整练习以后,不一定意味着已经掌握了所有Python技术,但可以帮助学习者建立更加稳定的编码基础。
变量、字符串、列表、字典、循环以及条件判断,是后续编写Python程序时经常会使用到的基础内容。
很多人会觉得这些题目比较简单,因此学习时容易快速跳过。但真正开始写程序以后,经常出现的边界错误、数据类型问题以及条件判断遗漏,往往都和基础知识不够熟练有关。
下面是几道比较典型的基础练习。
n = int(input(”请输入数字:”))if n % 2 == 0:print(”偶数”)else:print(”奇数”)
这道题主要练习输入转换、取余运算以及条件判断。
s = input(”输入字符串:”).strip()if s == s[::-1]:print(”是回文字符串”)else:print(”不是回文字符串”)
通过这道题,可以熟悉字符串切片、输入清理以及比较操作。
total = 0for i in range(1, 101):total += iprint(total)
这道题涉及循环范围、变量累加以及循环结束后的结果输出。
这一阶段的主要目标,是看到相对简单的需求以后,不需要频繁翻阅教程,也能够自己组织出一段可以运行的代码。
练习时要重点熟悉容器操作、循环边界、字符串处理以及不同数据类型之间的转换,为后面的函数、文件处理和项目练习打下基础。
基础语法相对熟练以后,可以继续进入进阶练习。
这一部分可以围绕自定义函数、面向对象、文件读写、异常处理、正则表达式、JSON数据、装饰器以及模块调用等内容展开。
这些知识经常会出现在办公自动化、数据整理、文件批量处理以及简单工具开发当中。
with open(”note.txt”, ”a”, encoding=”utf-8”) as f:f.write(”新增一行测试文本\n”)
这段代码使用with管理文件打开和关闭,并通过追加模式写入内容。
练习时还可以继续尝试读取文件、覆盖写入以及逐行处理。
nums = [1, 2, 3, 4, 5, 6, 7, 8]result = list(filter(lambda x: x % 2 == 0, nums))print(result)
这道题可以用来理解匿名函数和filter()的基础使用方式。
不过,在实际代码中,也可以使用列表推导式完成相同需求:
result = [x for x in nums if x % 2 == 0]比较两种写法,有助于理解不同代码风格在可读性方面的区别。
try:num = int(input(”输入数字:”))print(10 / num)except ZeroDivisionError:print(”错误:不能除以0”)except ValueError:print(”错误:请输入合法数字”)
异常处理并不是简单地让程序不报错,而是需要根据不同问题,给出相对应的处理方式。
class Student:def __init__(self, name):self.name = namedef say_hello(self):print(f”大家好,我是{self.name}”)stu = Student(”小明”)stu.say_hello()
这段代码可以帮助理解类、对象、属性以及方法之间的关系。
完成这一阶段的练习以后,可以尝试独立编写一些小型工具,例如批量重命名文件、整理指定目录、读取日志内容或者处理简单表格数据。
这些项目规模不一定很大,但能够帮助学习者逐渐从“完成单独练习题”,过渡到“组织一段完整程序”。
基础语法决定了代码能不能正常写出来,而算法与数据结构,则会影响代码解决问题的效率和思路。
这一部分可以练习排序、二分查找、双指针、栈、队列、滑动窗口、深度优先搜索、广度优先搜索以及动态规划等常见内容。
算法题不只用于准备面试,也能够训练如何把一个复杂需求拆分成较小的步骤。
def binary_search(arr, target):left, right = 0, len(arr) - 1while left <= right:mid = (left + right) // 2if arr[mid] == target:return midelif arr[mid] < target:left = mid + 1else:right = mid - 1return -1print(binary_search([1, 2, 3, 4, 5, 6], 4))
二分查找适用于已经排序的数据。它的关键不是记住代码,而是理解每一次比较以后,为什么可以排除一半的查找范围。
def two_sum(nums, target):hash_map = {}for index, num in enumerate(nums):need = target - numif need in hash_map:return [hash_map[need], index]hash_map[num] = indexreturn []print(two_sum([2, 7, 11, 15], 9))
这道题可以帮助理解哈希表在快速查找方面的作用。
练习时还可以思考,使用两层循环能不能完成,以及两种方法在时间复杂度方面存在什么区别。
def max_sub_array(nums):if not nums:raise ValueError(”列表不能为空”)current_sum = max_sum = nums[0]for value in nums[1:]:current_sum = max(value, current_sum + value)max_sum = max(max_sum, current_sum)return max_sumprint(max_sub_array([-2, 1, -3, 4, -1, 2, 1, -5, 4]))
这道题通常使用Kadane算法解决。
理解时需要重点关注:为什么当前位置的最优结果,只需要在“从当前元素重新开始”和“接在前面的结果之后”之间进行选择。
刷算法题时,不建议只背固定代码。更加重要的是理解题目条件、数据结构以及每一步处理的原因。同一道题可以尝试使用不同方法实现,再比较它们的效率和可读性。
拿到题目以后,可以先整理输入是什么、输出是什么,以及问题需要经过哪些步骤才能解决。
即使第一版代码不能正常运行,也不要马上复制参考答案。调试报错、检查变量和修改逻辑的过程,本身就是编程能力提升的重要部分。
如果完全没有思路,可以先查看提示,而不是直接查看完整代码。
如果循环、函数和数据类型还不够熟练,就直接进入复杂算法、深度学习或者大型框架,学习过程很容易出现断层。
可以按照“基础语法—函数与文件—项目脚本—数据结构与算法”的顺序逐渐推进。
学习速度可以根据自己的情况调整,但基础内容最好不要完全跳过。
遇到经常写错、反复卡住或者理解不清楚的题目,可以单独保存下来。
除了记录正确答案,还要写明:
自己最开始错在哪里、为什么会出错、后来采用了什么方法,以及是否还有其他实现方式。
每隔一段时间重新完成一次,比单纯查看原来的代码更容易检验是否真正掌握。
刷题只是训练方式,并不是最终目标。
掌握文件读写以后,可以尝试制作文件整理工具;学会列表和字典以后,可以完成简单的数据统计;掌握正则表达式以后,可以处理文本内容;学习网络请求时,则应在公开接口、个人项目或者明确授权的数据范围内进行练习。
把多个知识点组合到一个小项目中,才能逐渐形成完整的开发思路。学习Python并不意味着必须在短时间内掌握大量第三方框架和各种新技术。
对于初学者来说,更需要优先建立的是基础语法、逻辑分析、代码组织以及错误排查能力。
与其不断收藏新的课程,不如选择一套难度逐步增加的练习题,一道一道完成,并在每次练习以后总结自己的问题。
当你能够独立分析需求、拆分步骤、编写代码并排查错误时,就说明自己已经逐渐摆脱了只能跟随教程操作的阶段。
150道题并不是所谓的编程终点,而是一条用来训练基础能力的学习路线。真正的提升,仍然需要继续结合项目、文档和实际需求,反复练习并不断完善自己的代码。