Python编程思维训练:100道练习题带你从语法到实战
很多Python初学者都有这样的困惑:跟着教程学完了语法,但一遇到实际问题就无从下手,写出来的代码要么报错,要么逻辑混乱。这背后真正的问题,不是语法没记住,而是缺乏将问题拆解为代码逻辑的“编程思维”。
语法是“单词”,而编程思维是“造句和写文章”的能力。单纯背单词,永远学不会写作。这篇文章要解决的,就是帮你跨越从“懂语法”到“会编程”这道最关键的鸿沟。我们不会空谈理论,而是通过一套精心设计的、覆盖六大核心知识领域的100道练习题,带你进行高强度、系统化的思维训练。
我的核心判断是:对于初学者而言,通过大量、分类、循序渐进的练习来建立肌肉记忆和条件反射,远比反复阅读理论有效得多。这100道题就像一个“编程健身房”,每一组练习都针对特定的“思维肌肉群”。一周的密集训练后,你将能条件反射般地处理变量、循环、数据结构、函数、文件乃至面向对象的问题。
下面,我们就从最核心的“编程思维”开始,进入这100道题的实战训练场。
1. 编程思维:从问题到代码的“翻译”艺术
在动手写第一行代码之前,我们必须先统一思想:编程的本质是什么?是把人类语言描述的问题,“翻译”成计算机能理解和执行的精确指令。这个“翻译”过程,就是编程思维。
一个典型的思维误区:很多新手看到题目“计算1到100的和”,立刻开始写for i in range(1, 101):。这没错,但这是结果,不是过程。正确的思维路径应该是:
- 理解问题:需要得到一个累加的结果。
- 设计“容器”:需要一个变量(比如
total)来存放这个不断变化的累加和。 - 设计“流水线”:需要一个机制,能按顺序生成1,2,3,...,100这些数字。
- 组装逻辑:让流水线吐出的每个数字,都加到
total这个容器里。 - 输出结果:流水线结束后,容器里的值就是答案。
这个过程,就是自顶向下,逐步细化。我们后面的所有练习,都在强化这种思维模式。
2. 环境准备:搭建你的Python练习场
工欲善其事,必先利其器。一个稳定、简单的开发环境能让你更专注于思维训练。
2.1 Python安装与验证
访问Python官网(python.org)下载最新稳定版(如3.11+)。安装时务必勾选“Add Python to PATH”,这是后续一切顺利的基础。
安装后,打开命令行(Windows: CMD或PowerShell; Mac/Linux: Terminal),验证安装:
python --version # 或 python3 --version应显示类似Python 3.11.5的信息。
2.2 选择你的代码编辑器
对于练习阶段,轻量级、启动快的编辑器是首选。
- VS Code:功能强大,插件丰富。安装Python扩展后体验极佳。
- PyCharm Community Edition:专为Python设计,智能提示和调试功能强大。
- Sublime Text / Atom:轻量快速,适合专注编码。
关键建议:在练习初期,尽量少用编辑器的自动补全,尝试自己回忆和拼写函数、关键字,这能加深记忆。
2.3 创建项目结构
建立一个专属的练习文件夹,例如python_100_exercises,内部按天数或知识点建立子文件夹,便于管理。
python_100_exercises/ ├── day1_basics/ ├── day2_control_flow/ ├── day3_data_structures/ ├── day4_functions/ ├── day5_file_io/ ├── day6_oop/ └── solutions/ # 存放你自己的答案,先不要看参考答案3. 基础语法与变量:建立程序世界的“砖块”(第1-20题)
这是夯实基础的阶段,目标是形成对变量、数据类型和基本运算的本能反应。
3.1 核心概念与常见“坑”
- 变量命名:不仅仅是语法要求(字母、数字、下划线,不以数字开头),更是为了可读性。
user_age远优于ua。 - 动态类型:Python中变量类型由赋予的值决定。这很灵活,但也容易导致隐蔽的类型错误。
- 字符串格式化:掌握 f-string(Python 3.6+)是现代化、可读性最高的方式。
3.2 精选练习题与深度解析
题目1:交换两个变量的值。
# 新手常见写法:引入临时变量 a = 5 b = 10 temp = a a = b b = temp print(f"a = {a}, b = {b}") # a = 10, b = 5 # Pythonic写法:元组解包 a, b = 5, 10 a, b = b, a # 核心:右侧(b, a)先构成元组(10, 5),再解包赋值给左侧 print(f"a = {a}, b = {b}") # a = 10, b = 5思维要点:理解“元组解包”这个语法糖,它体现了Python的简洁哲学。思考:如果交换三个变量a, b, c = b, c, a会发生什么?
题目5:输入一个数字,判断是奇数还是偶数。
num = int(input("请输入一个整数: ")) # 关键:input()返回字符串,必须用int()转换 # 方法1:使用取模运算符 % if num % 2 == 0: print(f"{num} 是偶数") else: print(f"{num} 是奇数") # 方法2:使用位运算 & (效率更高,理解二进制) if num & 1: # 奇数二进制最后一位是1,与1进行位与运算结果为1(True) print(f"{num} 是奇数") else: print(f"{num} 是偶数")思维要点:1. 类型转换是输入处理的必由之路。2. 同一个问题可以有多种解法,思考不同解法的优劣(可读性 vs 性能)。
题目15:将华氏温度转换为摄氏温度。公式:C = (F - 32) / 1.8
fahrenheit = float(input("请输入华氏温度: ")) celsius = (fahrenheit - 32) / 1.8 # 格式化输出:控制小数位数 print(f"对应的摄氏温度是: {celsius:.2f}°C") # :.2f 表示保留两位小数思维要点:1. 涉及除法的计算,输入应考虑使用float。2. 格式化输出是提升程序友好度的关键技能。
4. 流程控制:让程序学会“思考”与“重复”(第21-40题)
掌握了砖块,现在学习如何用条件(if)和循环(for/while)这些“钢筋水泥”来构建逻辑。
4.1 核心:避免无限循环与优化循环
forvswhile:for用于已知迭代次数或遍历集合;while用于条件满足即持续运行。- 循环控制:
break(彻底跳出)、continue(跳过本次剩余代码,进入下一轮)是控制循环流程的利器。 - 无限循环陷阱:
while循环必须有改变条件变量的语句,否则会死循环。
4.2 精选练习题与深度解析
题目25:打印九九乘法表。
# 嵌套循环的经典入门题 for i in range(1, 10): # 外层控制行数 for j in range(1, i + 1): # 内层控制每行的列数,第i行有i列 # 使用格式化字符串对齐输出,\t是制表符,保证对齐 print(f"{j} x {i} = {i*j:2d}", end="\t") # :2d 保证结果占2位,右对齐 print() # 换行思维要点:理解嵌套循环中,外层循环变量(i)如何在内层循环中作为边界条件(range(1, i+1))。这是理解复杂循环逻辑的基础。
题目32:寻找100以内的所有素数。
# 素数定义:大于1的自然数,除了1和自身外无法被其他数整除 print("100以内的素数有:") for num in range(2, 101): # 从2开始 is_prime = True # 先假设它是素数 # 优化:只需检查到 num 的平方根即可 for i in range(2, int(num ** 0.5) + 1): if num % i == 0: # 如果能被整除 is_prime = False break # 发现一个因子就不是素数,立即跳出内层循环 if is_prime: print(num, end=" ")思维要点:1.标志变量(Flag):is_prime是一个典型的标志,用于记录中间状态。2.算法优化:检查范围到平方根即可,这是数学知识在编程中的应用,能大幅减少不必要的计算。
题目38:模拟一个简单的猜数字游戏。
import random target = random.randint(1, 100) # 生成1-100的随机整数 count = 0 print("猜数字游戏开始!目标在1到100之间。") while True: # 使用无限循环,靠break退出 guess = int(input("请输入你的猜测: ")) count += 1 if guess < target: print("猜小了!") elif guess > target: print("猜大了!") else: print(f"恭喜你!猜对了!你一共猜了{count}次。") break # 猜对,退出循环思维要点:1.while True与break的组合是处理未知次数循环的常用模式。2. 引入random模块,理解如何利用标准库扩展程序功能。
5. 核心数据结构:组织数据的“容器大师”(第41-65题)
列表、元组、字典、集合是Python的四大核心数据结构,是存储和处理数据的基石。
5.1 数据结构选用指南
- 列表
list:有序,可变,可重复。用途最广,当你不确定用什么时,先用列表。 - 元组
tuple:有序,不可变,可重复。用于保护数据不被修改,常作为字典的键或函数返回多个值。 - 字典
dict:键值对,无序(Python 3.7+有序),键不可重复。用于快速通过唯一键查找值。 - 集合
set:无序,不可重复,元素不可变。用于去重和集合运算(交、并、差)。
5.2 精选练习题与深度解析
题目45:统计一个列表中每个元素出现的次数。
# 方法1:使用字典手动统计(理解原理) my_list = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple'] count_dict = {} for item in my_list: if item in count_dict: # 如果键已存在 count_dict[item] += 1 else: # 如果键不存在 count_dict[item] = 1 print(count_dict) # 输出:{'apple': 3, 'banana': 2, 'orange': 1} # 方法2:使用 collections.Counter(专业工具) from collections import Counter count_dict_2 = Counter(my_list) print(count_dict_2) # 输出:Counter({'apple': 3, 'banana': 2, 'orange': 1}) print(dict(count_dict_2)) # 可以转换回普通字典思维要点:1. 字典的key in dict操作是高效的。2. 了解并善用标准库中的高级工具(如Counter),它们是Python生产力的体现。
题目52:列表去重,并保持原有顺序。
# 输入列表 original_list = [3, 1, 2, 1, 4, 2, 3, 5] # 方法1:利用字典在Python 3.7+的有序性(最Pythonic) unique_list_1 = list(dict.fromkeys(original_list)) print(unique_list_1) # 输出:[3, 1, 2, 4, 5] # 方法2:使用循环和空列表(理解过程) unique_list_2 = [] for item in original_list: if item not in unique_list_2: # 如果新列表中没有该元素 unique_list_2.append(item) # 则添加 print(unique_list_2) # 输出:[3, 1, 2, 4, 5] # 注意:直接使用 set() 会丢失顺序! # print(list(set(original_list))) # 输出顺序可能是 [1, 2, 3, 4, 5]思维要点:1. 理解“保持顺序”这一需求的重要性。2.dict.fromkeys()是一个巧妙利用字典键唯一性且保持插入顺序的方法。
题目60:合并两个字典。
dict1 = {'a': 1, 'b': 2} dict2 = {'b': 3, 'c': 4} # 注意键'b'重复 # 方法1:Python 3.5+ 使用 ** 解包(推荐) merged_dict_1 = {**dict1, **dict2} # 后面的字典覆盖前面的 print(merged_dict_1) # 输出:{'a': 1, 'b': 3, 'c': 4} # 方法2:使用 update() 方法(原地修改) dict1_copy = dict1.copy() # 避免修改原字典 dict1_copy.update(dict2) print(dict1_copy) # 输出:{'a': 1, 'b': 3, 'c': 4} # 方法3:Python 3.9+ 使用 | 运算符 # merged_dict_3 = dict1 | dict2 # 同样,后者覆盖前者思维要点:1. 明确合并规则:键冲突时,后者的值覆盖前者。2. 根据Python版本选择最优雅的写法。
6. 函数:封装与复用的“魔法盒”(第66-80题)
函数是将一段代码逻辑打包,以便重复使用的工具。好的函数是构建大型程序的基石。
6.1 函数设计原则
- 单一职责:一个函数只做好一件事。
- 命名清晰:函数名应清晰描述其功能(动词开头,如
calculate_average,get_user_input)。 - 参数与返回值:明确输入是什么,输出是什么。尽量让函数成为“纯函数”(输出仅由输入决定,无副作用)。
6.2 精选练习题与深度解析
题目68:编写一个函数,计算任意数量的数字的平均值。
# 使用 *args 接收可变数量的位置参数 def calculate_average(*numbers): """ 计算任意数量数字的平均值。 参数: *numbers: 可变数量的数字参数。 返回: 这些数字的平均值。如果未提供数字,返回0。 """ if not numbers: # 处理空参数的情况 return 0 return sum(numbers) / len(numbers) # 测试 print(calculate_average(1, 2, 3, 4, 5)) # 输出:3.0 print(calculate_average(10, 20)) # 输出:15.0 print(calculate_average()) # 输出:0思维要点:1.*args的用法,它把传入的参数打包成一个元组。2.防御性编程:考虑边界情况,如参数为空。3. 使用文档字符串(""")说明函数用途,这是好习惯。
题目73:利用递归计算斐波那契数列的第n项。
def fibonacci_recursive(n): """ 递归计算斐波那契数列第n项。 警告:此方法效率极低,仅用于演示递归思想。 """ if n <= 0: return 0 elif n == 1: return 1 else: return fibonacci_recursive(n-1) + fibonacci_recursive(n-2) # 测试 print(fibonacci_recursive(10)) # 输出:55 # 高效方法:使用迭代(动态规划思想) def fibonacci_iterative(n): if n <= 0: return 0 elif n == 1: return 1 a, b = 0, 1 # 分别代表 F(0) 和 F(1) for _ in range(2, n + 1): a, b = b, a + b # 同时更新,b变为新的F(i) return b print(fibonacci_iterative(10)) # 输出:55 (更快)思维要点:1. 理解递归的“自我调用”和“基线条件”(n<=0和n==1)。2.认识到递归的性能缺陷:存在大量重复计算。3. 引入迭代解法,理解空间换时间/动态规划的初步思想。
题目78:编写一个装饰器,用来测量函数的执行时间。
import time def timer_decorator(func): """装饰器:打印被装饰函数的运行时间。""" def wrapper(*args, **kwargs): # 接收任意参数 start_time = time.time() # 记录开始时间 result = func(*args, **kwargs) # 执行原函数 end_time = time.time() # 记录结束时间 print(f"函数 {func.__name__} 运行耗时: {end_time - start_time:.6f} 秒") return result # 返回原函数的执行结果 return wrapper # 使用装饰器 @timer_decorator def slow_function(seconds): """模拟一个耗时的函数""" time.sleep(seconds) return f"睡了{seconds}秒" # 调用 print(slow_function(2)) # 输出: # 函数 slow_function 运行耗时: 2.005234 秒 # 睡了2秒思维要点:1. 装饰器是Python的高级特性,本质是“函数的函数”。2.wrapper函数接收*args, **kwargs以保证能装饰任何函数。3. 理解装饰器在代码复用和横切关注点(如日志、计时、权限检查)上的强大作用。
7. 文件操作与数据持久化:与外部世界“对话”(第81-90题)
程序不能只活在内存里,需要读取外部数据,也需要保存结果。
7.1 文件操作核心:with语句
使用with open(...) as f:是唯一推荐的方式。它能自动管理文件资源,确保在任何情况下(包括发生异常)文件都会被正确关闭,避免资源泄漏。
7.2 精选练习题与深度解析
题目83:读取一个文本文件,统计其中单词的出现频率。
def count_words(filename): """ 统计文本文件中每个单词的出现频率。 参数: filename: 文本文件的路径。 返回: 一个字典,键为单词,值为出现次数。 """ word_count = {} try: with open(filename, 'r', encoding='utf-8') as file: for line in file: # 清洗数据:转小写,去除标点,分割单词 # 更健壮的做法可以使用正则表达式 re.findall(r'\b\w+\b', line.lower()) words = line.lower().strip().replace(',', '').replace('.', '').split() for word in words: word_count[word] = word_count.get(word, 0) + 1 except FileNotFoundError: print(f"错误:文件 '{filename}' 未找到。") return {} except Exception as e: print(f"读取文件时发生未知错误: {e}") return {} return word_count # 假设有一个 'sample.txt' 文件,内容为 "Hello world, hello Python. Python is great!" result = count_words('sample.txt') # 按频率降序排序并打印 for word, count in sorted(result.items(), key=lambda item: item[1], reverse=True): print(f"{word}: {count}")思维要点:1.异常处理:文件操作必须考虑文件不存在、编码错误等异常。2.数据清洗:原始文本需要处理(大小写、标点)才能得到准确的单词。3.dict.get(key, default)方法是处理键可能不存在的优雅方式。
题目87:将一个字典或列表数据写入JSON文件,并重新读取。
import json # 要保存的数据 data_to_save = { "name": "张三", "age": 25, "courses": ["Python", "数据结构", "算法"], "is_student": True } # 1. 写入JSON文件 filename = 'data.json' try: with open(filename, 'w', encoding='utf-8') as f: # indent 参数使JSON格式化输出,便于阅读 json.dump(data_to_save, f, ensure_ascii=False, indent=4) print(f"数据已成功写入文件 {filename}") except IOError as e: print(f"写入文件失败: {e}") # 2. 从JSON文件读取 try: with open(filename, 'r', encoding='utf-8') as f: loaded_data = json.load(f) print("从文件读取的数据:") print(json.dumps(loaded_data, ensure_ascii=False, indent=4)) # 美化打印 # 访问数据 print(f"姓名: {loaded_data['name']}") print(f"课程: {', '.join(loaded_data['courses'])}") except FileNotFoundError: print(f"文件 {filename} 不存在") except json.JSONDecodeError as e: print(f"JSON解析错误: {e}")思维要点:1. JSON是跨语言的数据交换格式,json模块使其在Python中易于使用。2.ensure_ascii=False允许正常显示中文等非ASCII字符。3.indent参数对调试非常友好。4. 再次强调异常处理的重要性。
8. 面向对象编程(OOP):用对象“建模”现实(第91-100题)
OOP不是语法,而是一种组织代码、模拟现实世界的思维方式。
8.1 OOP四大支柱
- 封装:将数据(属性)和操作数据的方法(函数)捆绑在一起,隐藏内部细节。
- 继承:子类可以继承父类的属性和方法,实现代码复用和层次化分类。
- 多态:不同类的对象可以对同一消息(方法调用)做出不同的响应。
- 抽象:定义接口或抽象类,隐藏复杂的实现细节。
8.2 精选练习题与深度解析
题目94:设计一个简单的银行账户类(BankAccount)。
class BankAccount: """一个简单的银行账户类""" # 类属性:所有账户共享的利率 interest_rate = 0.03 # 年利率3% def __init__(self, account_holder, initial_balance=0): """构造方法,初始化账户""" # 实例属性:每个账户独有的 self.account_holder = account_holder # 账户持有人 self.__balance = initial_balance # 余额(私有属性,以双下划线开头) self.transactions = [] # 交易记录列表 self._add_transaction(f"账户开户,初始余额: {initial_balance}") def _add_transaction(self, description): """私有方法:添加交易记录(内部使用)""" self.transactions.append(description) def deposit(self, amount): """存款""" if amount <= 0: print("存款金额必须大于0。") return False self.__balance += amount self._add_transaction(f"存款: +{amount}") print(f"成功存款 {amount}。当前余额: {self.__balance}") return True def withdraw(self, amount): """取款""" if amount <= 0: print("取款金额必须大于0。") return False if amount > self.__balance: print("余额不足。") return False self.__balance -= amount self._add_transaction(f"取款: -{amount}") print(f"成功取款 {amount}。当前余额: {self.__balance}") return True def apply_interest(self): """应用年利息""" interest = self.__balance * self.interest_rate self.__balance += interest self._add_transaction(f"利息收入: +{interest:.2f}") print(f"利息 {interest:.2f} 已计入账户。当前余额: {self.__balance}") def get_balance(self): """获取当前余额(提供访问私有属性的接口)""" return self.__balance def display_info(self): """显示账户信息""" print(f"账户持有人: {self.account_holder}") print(f"当前余额: {self.__balance}") print("最近交易记录:") for trans in self.transactions[-5:]: # 显示最近5条 print(f" - {trans}") # 使用示例 if __name__ == "__main__": # 创建账户 account1 = BankAccount("小明", 1000) # 存款 account1.deposit(500) # 取款(成功) account1.withdraw(200) # 取款(失败,余额不足) account1.withdraw(2000) # 应用利息 account1.apply_interest() # 查看余额(通过方法,不能直接访问 __balance) print(f"最终余额(通过方法): {account1.get_balance()}") # 显示信息 account1.display_info()思维要点:1.__init__是构造器。2.封装:私有属性__balance和私有方法_add_transaction(单下划线约定为保护,双下划线触发名称修饰)。3. 通过公有方法(deposit,withdraw,get_balance)来访问和修改私有属性,这是封装的精髓。4. 类属性interest_rate与实例属性的区别。
题目98:实现一个简单的图形类层次结构(Shape -> Circle, Rectangle)。
import math class Shape: """形状基类(抽象)""" def area(self): """计算面积(抽象方法,子类必须实现)""" raise NotImplementedError("子类必须实现 area() 方法") def perimeter(self): """计算周长(抽象方法,子类必须实现)""" raise NotImplementedError("子类必须实现 perimeter() 方法") def display_info(self): """显示形状信息(多态的基础)""" print(f"{self.__class__.__name__}: 面积={self.area():.2f}, 周长={self.perimeter():.2f}") class Circle(Shape): """圆形类,继承自Shape""" def __init__(self, radius): self.radius = radius def area(self): return math.pi * self.radius ** 2 def perimeter(self): return 2 * math.pi * self.radius class Rectangle(Shape): """矩形类,继承自Shape""" def __init__(self, width, height): self.width = width self.height = height def area(self): return self.width * self.height def perimeter(self): return 2 * (self.width + self.height) # 使用示例:体验多态 if __name__ == "__main__": shapes = [ Circle(5), Rectangle(4, 6), Circle(3), Rectangle(2, 8) ] for shape in shapes: shape.display_info() # 同一个方法调用,不同对象产生不同行为思维要点:1.继承:Circle和Rectangle继承Shape,获得了display_info方法。2.多态:shape.display_info()会调用各自类的area()和perimeter(),这是运行时决定的。3.抽象:基类Shape定义了接口(area,perimeter),但不提供实现,强制子类完成。
9. 常见问题与排查思路(FAQ)
在练习过程中,你几乎一定会遇到下面这些问题。别担心,它们都是进步的阶梯。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
SyntaxError: invalid syntax | 语法错误,如括号/引号不匹配、冒号缺失、缩进混用空格和Tab。 | 查看错误行及上一行。检查所有成对符号。 | 使用IDE的语法高亮和自动格式化功能。统一使用4个空格缩进。 |
NameError: name ‘xxx’ is not defined | 变量或函数名拼写错误,或在使用后才定义。 | 检查变量名是否前后一致(大小写敏感)。确认变量定义在使用之前。 | 仔细核对拼写。确保函数调用在函数定义之后。 |
IndentationError: unexpected indent | 缩进错误,多出或缺少了空格。 | 检查错误行的缩进是否与上下文一致。 | 在编辑器中显示空格/制表符,确保缩进一致。 |
TypeError: can only concatenate str (not “int”) to str | 类型错误,如字符串和数字直接相加。 | 检查+操作符两边的数据类型。 | 使用str()将数字转为字符串,或使用 f-string 格式化。 |
ZeroDivisionError: division by zero | 除数为零。 | 检查除法运算中分母变量的值。 | 在除法前添加判断if denominator != 0:。 |
IndexError: list index out of range | 列表索引超出范围。列表长度为n,有效索引是0到n-1。 | 打印列表长度len(list)和你尝试访问的索引。 | 使用索引前确保它< len(list)。考虑使用for item in list:遍历。 |
KeyError: ‘some_key’ | 字典中不存在的键。 | 检查字典的键名拼写。 | 使用dict.get(key, default_value)方法安全访问,或先用key in dict判断。 |
AttributeError: ‘xxx’ object has no attribute ‘yyy’ | 对象没有这个属性或方法。 | 检查对象类型是否正确,方法名是否拼写错误。 | 使用dir(object)查看对象所有属性和方法。检查类定义。 |
| 程序逻辑正确,但结果不对 | 算法逻辑有误,或边界条件没处理好。 | 使用print()调试法,在关键步骤打印变量值。 | 逐步跟踪程序执行流程,画出流程图或使用调试器(如VS Code的调试功能)。 |
导入模块失败ModuleNotFoundError | 模块未安装,或不在Python路径中。 | 确认模块名拼写。在命令行尝试pip list查看已安装包。 | 使用pip install module_name安装。检查PyCharm项目解释器或VS Code的Python环境。 |
10. 最佳实践与工程化建议
当你完成这100道题,开始转向真实项目时,请牢记以下建议:
- 先写伪代码,再写真实代码:用中文或英文写下步骤,理清逻辑,这是避免思维混乱的最有效方法。
- 一个函数只做一件事:函数越长,越容易出错,越难调试。超过30行的函数,考虑拆分。
- 给变量和函数起个好名字:
calculate_monthly_revenue比calc好一万倍。名字是代码的文档。 - 拥抱版本控制(Git):从现在开始就学习使用Git(如GitHub Desktop)。每次完成一个功能或练习就提交一次,这是程序员的“后悔药”。
- 编写可测试的代码:尝试为你写的函数编写简单的测试。例如,写一个
test_calculate_average()函数,用几个已知输入输出验证你的函数。 - 善用官方文档和搜索引擎:遇到问题,第一反应是查官方文档(
docs.python.org)。其次,在搜索引擎用英文关键词搜索(如“python list remove duplicate keep order”),通常比中文搜索找到的答案更权威。 - 阅读优秀的代码:在GitHub上找一些星标高的Python项目,看看别人是怎么组织代码、命名变量、处理异常的。
- 不要害怕错误:每一个错误信息都是Python解释器在努力告诉你哪里出了问题。学会阅读并理解错误信息,是独立解决问题的关键能力。
这100道练习题是一个起点,而不是终点。它们为你构建了从基础语法到面向对象的完整知识框架和思维模式。真正的“老腻害”,来自于将这些模式应用于无数个真实、复杂、甚至定义模糊的问题中。下一步,你可以尝试用这些技能去解决一个小问题:写一个通讯录管理程序、一个简单的网页爬虫、一个数据分析脚本,或者一个自动化处理Excel报表的工具。当你用代码让重复的工作自动运行起来时,你会获得前所未有的成就感,那才是编程真正迷人的开始。
