很多朋友在学完Python基础语法后,面对实际项目或解决具体问题时,常常感到无从下手,觉得“学完了”但“不会用”。这通常是因为缺乏系统性的、从易到难的编程思维训练。本文为你精心整理了100道Python实战练习题,覆盖从基础语法到进阶算法的核心知识点。通过一周的刻意练习,每天攻克十几道题,你将能显著提升代码思维、问题拆解和调试能力,真正将Python语法内化为编程技能。无论你是准备面试、巩固基础,还是寻求突破,这套练习都能提供一条清晰的进阶路径。
1. 练习的价值与学习路径规划
1.1 为什么“刷题”对编程学习至关重要
单纯阅读教程或观看视频是一种被动学习,知识留存率很低。编程本质上是一项技能,如同游泳或驾驶,必须通过亲手实践才能掌握。练习题的作用在于:
- 巩固语法:将抽象的
for循环、if判断、函数定义等语法,在具体问题中反复运用,形成肌肉记忆。 - 训练思维:学习如何将复杂的现实问题,分解为计算机可以执行的步骤(算法)。
- 熟悉常见模式:许多编程问题背后是共通的模式,如遍历、查找、排序、递归等,通过练习可以识别并熟练运用这些模式。
- 提升调试能力:自己写的代码出错是常态,通过解决练习题中的错误,你能更快地理解报错信息,掌握排查技巧。
1.2 如何使用这100道练习题
建议采用“循序渐进、定时定量、复盘总结”的方法:
- 循序渐进:题目已按大致难度排列。请务必从第一题开始,确保基础牢固后再挑战后续题目。
- 定时定量:建议每天花费1-2小时,完成10-15道题。保持节奏比一次性突击更有效。
- 复盘总结:每做完一道题,思考是否有更优解?代码能否更简洁?遇到卡壳的地方,正是你需要重点攻克的知识点,务必弄懂。
- 独立完成:尽量先独立思考并编写代码,调试运行。实在无法解决时,再参考答案或寻求帮助,并理解答案的思路。
1.3 环境准备
你需要一个可以运行Python代码的环境。
- 安装Python:访问Python官网下载安装包。建议选择Python 3.7及以上版本。安装时务必勾选“Add Python to PATH”。
- 选择编辑器:初学者可以使用IDLE(Python自带)或VS Code、PyCharm等。本文示例代码在标准Python交互环境或任何编辑器中均可运行。
- 验证安装:打开命令行(Windows: CMD/PowerShell, Mac/Linux: Terminal),输入
python --version或python3 --version,看到版本号即表示安装成功。
2. 基础语法巩固练习 (第1-30题)
这部分题目旨在夯实Python最核心的语法基础,包括变量、数据类型、运算符、流程控制等。
2.1 变量与数据类型
题目1:数字求和编写程序,接收用户输入的两个数字,计算它们的和、差、积、商(保留两位小数)并输出。
# 示例代码框架 num1 = float(input("请输入第一个数字:")) num2 = float(input("请输入第二个数字:")) print(f"和:{num1 + num2}") print(f"差:{num1 - num2}") print(f"积:{num1 * num2}") # 注意除零错误 if num2 != 0: print(f"商:{num1 / num2:.2f}") else: print("商:除数不能为零")关键点:input()获取字符串输入,需要用float()或int()转换;使用f-string格式化输出;进行除零判断。
题目2:字符串操作接收用户输入的一个字符串,分别输出其长度、大写形式、小写形式,并判断是否以“Python”开头。
my_str = input("请输入一个字符串:") print(f"字符串长度:{len(my_str)}") print(f"大写形式:{my_str.upper()}") print(f"小写形式:{my_str.lower()}") print(f"是否以‘Python’开头:{my_str.startswith('Python')}")2.2 条件判断与循环
题目3:判断闰年输入一个年份,判断它是否是闰年。闰年规则:能被4整除但不能被100整除,或者能被400整除。
year = int(input("请输入年份:")) if (year % 4 == 0 and year % 100 != 0) or (year % 400 == 0): print(f"{year}年是闰年") else: print(f"{year}年不是闰年")题目4:数字猜谜游戏程序随机生成一个1-100之间的整数,用户有7次机会猜测。每次猜测后,程序提示“太大了”、“太小了”或“恭喜猜对!”。机会用尽则游戏结束。
import random target = random.randint(1, 100) chances = 7 print("猜数字游戏开始!目标是一个1-100之间的整数。") for i in range(chances): guess = int(input(f"第{i+1}次猜测,请输入数字:")) if guess == target: print("恭喜你,猜对了!") break elif guess > target: print("太大了!") else: print("太小了!") else: # 当for循环正常结束(未被break中断)时执行 print(f"很遗憾,机会用尽。正确答案是{target}。")关键点:random.randint()的使用;for-else语句的妙用,当循环因break退出时不执行else,正常结束则执行。
题目5:打印九九乘法表使用嵌套循环打印出标准的九九乘法表。
for i in range(1, 10): for j in range(1, i+1): # 使用制表符 \t 对齐, end='' 使打印不换行 print(f"{j}×{i}={i*j}\t", end='') print() # 内层循环结束后换行2.3 列表、元组与字典
题目6:列表去重给定一个包含重复元素的列表,生成一个新列表,其中的元素是原列表的去重结果,并保持原有顺序。
original_list = [1, 2, 2, 3, 4, 4, 5, 1, 6] unique_list = [] for item in original_list: if item not in unique_list: unique_list.append(item) print(unique_list) # 输出:[1, 2, 3, 4, 5, 6] # 进阶:使用字典(Python 3.7+ 字典保持插入顺序)或 collections.OrderedDict # unique_list = list(dict.fromkeys(original_list))题目7:统计字符频率输入一个字符串,统计其中每个字符出现的次数,忽略大小写(即‘A’和‘a’算同一个字符)。
text = input("请输入一段文本:").lower() # 转换为小写 char_count = {} for char in text: # 只统计字母和数字,忽略空格和标点?这里统计所有字符 # if char.isalnum(): # 只统计字母数字 char_count[char] = char_count.get(char, 0) + 1 print("字符出现频率:") for char, count in char_count.items(): print(f"'{char}': {count}")题目8:合并两个字典合并两个字典,如果键重复,则将对应的值相加。
dict1 = {'a': 100, 'b': 200, 'c': 300} dict2 = {'a': 50, 'b': 150, 'd': 400} result = dict1.copy() # 先复制dict1 for key, value in dict2.items(): result[key] = result.get(key, 0) + value print(result) # 输出:{'a': 150, 'b': 350, 'c': 300, 'd': 400} # 进阶:使用 collections.Counter # from collections import Counter # result = Counter(dict1) + Counter(dict2)3. 函数与模块化编程练习 (第31-50题)
这部分重点练习函数的定义、参数传递、返回值以及利用函数组织代码。
3.1 函数定义与使用
题目9:计算阶乘编写一个函数factorial(n),计算并返回整数n的阶乘。要求处理n为0或负数的情况。
def factorial(n): if not isinstance(n, int) or n < 0: return None # 或抛出异常 raise ValueError("输入必须为非负整数") result = 1 for i in range(2, n+1): result *= i return result # 测试 print(factorial(5)) # 120 print(factorial(0)) # 1 print(factorial(-1)) # None题目10:判断素数编写一个函数is_prime(num),判断一个大于1的整数是否为素数(质数)。
def is_prime(num): if num <= 1: return False # 只需检查到 sqrt(num) 即可 for i in range(2, int(num ** 0.5) + 1): if num % i == 0: return False return True # 测试 print(is_prime(17)) # True print(is_prime(25)) # False3.2 递归与高阶函数
题目11:斐波那契数列(递归)使用递归函数生成斐波那契数列的第n项。斐波那契数列:F(0)=0, F(1)=1, F(n)=F(n-1)+F(n-2) (n>=2)。
def fibonacci_recursive(n): if n <= 0: return 0 elif n == 1: return 1 else: return fibonacci_recursive(n-1) + fibonacci_recursive(n-2) # 测试 print([fibonacci_recursive(i) for i in range(10)]) # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]注意:此递归解法效率极低(指数级时间复杂度),因为存在大量重复计算。仅用于理解递归概念。
题目12:斐波那契数列(迭代)使用迭代(循环)的方式高效计算斐波那契数列的第n项。
def fibonacci_iterative(n): if n <= 0: return 0 a, b = 0, 1 for _ in range(1, n): a, b = b, a + b return b # 测试,计算第50项 print(fibonacci_iterative(50)) # 12586269025题目13:列表映射与过滤给定一个数字列表,使用map和filter函数完成以下操作:
- 将所有数字平方。
- 过滤出所有偶数。
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # 使用map进行平方 squared = list(map(lambda x: x ** 2, numbers)) print(f"平方后:{squared}") # 使用filter过滤偶数 evens = list(filter(lambda x: x % 2 == 0, numbers)) print(f"偶数:{evens}")4. 字符串与文件操作进阶 (第51-70题)
处理文本和文件是Python的强项,这部分练习将深入相关操作。
4.1 复杂字符串处理
题目14:反转字符串编写一个函数,反转一个字符串。不要使用内置的reversed()或切片[::-1],尝试自己实现。
def reverse_string(s): reversed_chars = [] # 从后向前遍历字符串,将字符加入列表 for i in range(len(s)-1, -1, -1): reversed_chars.append(s[i]) return ''.join(reversed_chars) # 测试 print(reverse_string("Hello, World!")) # !dlroW ,olleH # 当然,实际中最简洁的是 s[::-1]题目15:检查回文字符串判断一个字符串是否是回文(正读反读都一样),忽略空格、标点和大小写。
def is_palindrome(s): # 清理字符串:只保留字母数字,并转为小写 cleaned = ''.join(ch.lower() for ch in s if ch.isalnum()) return cleaned == cleaned[::-1] # 测试 print(is_palindrome("A man, a plan, a canal: Panama")) # True print(is_palindrome("race a car")) # False4.2 文件读写操作
题目16:文件词频统计读取一个文本文件(例如article.txt),统计文件中每个单词出现的频率,并输出出现频率最高的前10个单词及其次数。
import re from collections import Counter def count_words(filename): try: with open(filename, 'r', encoding='utf-8') as file: text = file.read().lower() # 读取并转为小写 except FileNotFoundError: print(f"文件 {filename} 未找到。") return # 使用正则表达式分割单词,\w+ 匹配一个或多个字母数字下划线 words = re.findall(r'\b\w+\b', text) word_counts = Counter(words) # 获取最常见的10个 most_common = word_counts.most_common(10) print("出现频率最高的10个单词:") for word, count in most_common: print(f"{word}: {count}") # 假设当前目录下有 article.txt 文件 count_words('article.txt')关键点:使用with open确保文件正确关闭;re.findall进行单词分割;collections.Counter简化计数。
题目17:CSV文件处理假设有一个students.csv文件,内容如下:
name,score,grade Alice,85,B Bob,92,A Charlie,78,C编写程序读取该文件,计算平均分,并将结果写入一个新的文件report.txt。
import csv def process_student_csv(input_file, output_file): total_score = 0 count = 0 students = [] # 读取CSV with open(input_file, 'r', encoding='utf-8') as csvfile: reader = csv.DictReader(csvfile) # 使用DictReader方便按列名访问 for row in reader: name = row['name'] score = int(row['score']) grade = row['grade'] total_score += score count += 1 students.append((name, score, grade)) if count == 0: average = 0 else: average = total_score / count # 写入报告 with open(output_file, 'w', encoding='utf-8') as txtfile: txtfile.write("学生成绩报告\n") txtfile.write("="*20 + "\n") for name, score, grade in students: txtfile.write(f"{name}: 分数 {score}, 等级 {grade}\n") txtfile.write("="*20 + "\n") txtfile.write(f"平均分:{average:.2f}\n") print(f"报告已生成至 {output_file}") process_student_csv('students.csv', 'report.txt')5. 面向对象编程练习 (第71-85题)
通过模拟现实世界的实体,练习类的定义、继承、封装和多态。
5.1 类与对象基础
题目18:定义“矩形”类创建一个Rectangle类,具有长度和宽度属性,以及计算面积和周长的方法。再创建一个Square类(正方形)继承自Rectangle。
class Rectangle: def __init__(self, length, width): self.length = length self.width = width def area(self): return self.length * self.width def perimeter(self): return 2 * (self.length + self.width) def __str__(self): return f"矩形(长={self.length}, 宽={self.width})" class Square(Rectangle): def __init__(self, side): # 调用父类的初始化方法,长和宽都等于边长 super().__init__(side, side) self.side = side # 也可以单独保存边长属性 def __str__(self): return f"正方形(边长={self.side})" # 测试 rect = Rectangle(5, 3) print(rect) # 矩形(长=5, 宽=3) print(f"面积:{rect.area()}") # 15 print(f"周长:{rect.perimeter()}") # 16 sq = Square(4) print(sq) # 正方形(边长=4) print(f"面积:{sq.area()}") # 16 print(f"周长:{sq.perimeter()}") # 165.2 模拟简单系统
题目19:简易银行账户系统设计一个BankAccount类,包含属性:账户名、账号、余额。方法包括:存款、取款、显示余额。取款时需检查余额是否充足。
class BankAccount: def __init__(self, account_holder, account_number, initial_balance=0.0): self.account_holder = account_holder self.account_number = account_number self.balance = initial_balance def deposit(self, amount): if amount > 0: self.balance += amount print(f"存款成功!存入 {amount:.2f} 元。当前余额:{self.balance:.2f} 元。") return True else: print("存款金额必须为正数。") return False def withdraw(self, amount): if amount <= 0: print("取款金额必须为正数。") return False if amount > self.balance: print(f"取款失败!余额不足。当前余额:{self.balance:.2f} 元。") return False self.balance -= amount print(f"取款成功!取出 {amount:.2f} 元。当前余额:{self.balance:.2f} 元。") return True def display_balance(self): print(f"账户 [{self.account_number}] - {self.account_holder}") print(f"当前余额:{self.balance:.2f} 元。") # 测试 account = BankAccount("张三", "123456789", 1000) account.display_balance() account.deposit(500) account.withdraw(2000) # 会失败 account.withdraw(300) account.display_balance()6. 算法与数据结构入门 (第86-100题)
这部分引入一些经典的算法和数据结构思想,是面试和进阶学习的重点。
6.1 排序与搜索
题目20:冒泡排序实现不使用内置的sorted()或list.sort(),自己实现冒泡排序算法对列表进行升序排序。
def bubble_sort(arr): n = len(arr) # 遍历所有数组元素 for i in range(n): # 最后 i 个元素已经排好序 swapped = False for j in range(0, n-i-1): # 如果当前元素大于下一个元素,则交换 if arr[j] > arr[j+1]: arr[j], arr[j+1] = arr[j+1], arr[j] swapped = True # 如果这一趟没有发生交换,说明已经有序,可以提前结束 if not swapped: break return arr # 测试 my_list = [64, 34, 25, 12, 22, 11, 90] print("排序前:", my_list) sorted_list = bubble_sort(my_list.copy()) # 使用copy避免修改原列表 print("排序后:", sorted_list)题目21:二分查找在一个已排序的列表中,使用二分查找算法查找目标值的位置(索引),如果找不到则返回-1。
def binary_search(sorted_list, target): left, right = 0, len(sorted_list) - 1 while left <= right: mid = (left + right) // 2 if sorted_list[mid] == target: return mid elif sorted_list[mid] < target: left = mid + 1 else: right = mid - 1 return -1 # 测试 sorted_nums = [2, 5, 8, 12, 16, 23, 38, 56, 72, 91] target = 23 index = binary_search(sorted_nums, target) if index != -1: print(f"目标值 {target} 在列表中的索引是 {index}") else: print(f"列表中未找到目标值 {target}")6.2 列表推导式与生成器
题目22:使用列表推导式利用列表推导式完成以下任务:
- 生成一个包含1到20所有偶数的列表。
- 将一个字符串列表中的所有字符串转换为大写。
- 从一个数字列表中过滤出所有正数并计算其平方。
# 1. 1-20的偶数 evens = [x for x in range(1, 21) if x % 2 == 0] print(evens) # [2, 4, 6, ..., 20] # 2. 字符串转大写 words = ['hello', 'world', 'python', 'csdn'] upper_words = [word.upper() for word in words] print(upper_words) # ['HELLO', 'WORLD', 'PYTHON', 'CSDN'] # 3. 过滤正数并平方 numbers = [-5, 3, -1, 8, 0, -2, 4] positive_squares = [x**2 for x in numbers if x > 0] print(positive_squares) # [9, 64, 16]题目23:生成斐波那契数列的生成器使用生成器函数(yield)来生成斐波那契数列,可以无限生成,也可以生成前N项。
def fibonacci_generator(n=None): """生成斐波那契数列的生成器。 n: 生成的数量,如果为None则无限生成(需谨慎使用)。 """ a, b = 0, 1 count = 0 while n is None or count < n: yield a a, b = b, a + b count += 1 # 生成前10项 print("前10项斐波那契数列:") for num in fibonacci_generator(10): print(num, end=' ') print() # 无限生成(需要break条件),例如生成直到某项大于1000 print("\n斐波那契数列直到大于1000:") for num in fibonacci_generator(): # 无限生成器 if num > 1000: break print(num, end=' ')7. 常见问题与调试技巧
在练习过程中,你一定会遇到各种错误。以下是几个高频问题及其解决方法。
7.1 语法与运行时错误
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
SyntaxError: invalid syntax | 代码不符合Python语法规则,如括号不匹配、冒号缺失、错误的关键字拼写。 | 仔细检查报错行及上一行的语法。使用编辑器的语法高亮功能。 |
IndentationError | 缩进不一致(混用空格和Tab)或缩进层级错误。 | 统一使用4个空格进行缩进。在编辑器中设置“将Tab转换为空格”。 |
NameError: name 'xxx' is not defined | 使用了未定义的变量名或函数名。 | 检查变量/函数名是否拼写错误,或者是否在引用之前定义。 |
TypeError: can only concatenate str (not "int") to str | 尝试将字符串与非字符串类型(如整数)直接相加。 | 使用str()函数将非字符串转换为字符串,或使用f-string、format()方法。 |
IndexError: list index out of range | 列表索引超出了列表的有效范围(如对一个空列表使用list[0])。 | 在访问列表元素前,检查列表长度len(list),或使用try...except捕获异常。 |
ZeroDivisionError: division by zero | 除数为零。 | 在进行除法运算前,判断除数是否为零。 |
7.2 逻辑错误排查
逻辑错误是代码能运行,但结果不对。排查方法:
- 打印中间变量:在关键步骤后使用
print()输出变量的值,观察是否符合预期。 - 使用调试器:学习使用IDE(如PyCharm, VS Code)的调试功能,可以逐行执行,查看变量变化。
- 简化问题:如果代码复杂,尝试先写一个最小化的、能复现问题的版本。
- 代码审查:休息一下,然后从头到尾默读自己的代码,或者向他人解释你的代码逻辑。
7.3 练习中的典型“坑”
- 可变对象作为函数默认参数:
def func(a, lst=[])中的lst在函数定义时就被创建,多次调用会共享同一个列表。应改为def func(a, lst=None): lst = lst or []。 - 在循环中修改迭代对象:在
for item in list:循环内部对list进行增删操作,可能导致意外结果或错误。应先创建副本或使用while循环。 - 浮点数精度问题:
0.1 + 0.2的结果不是精确的0.3。对于需要精确计算的场景(如金融),使用decimal模块。
8. 最佳实践与学习建议
完成这100道题只是一个开始。要成为一名优秀的Python开发者,还需要养成好的习惯。
8.1 编码风格与规范
- 遵循PEP 8:这是Python官方的风格指南。保持一致的缩进(4空格)、合理的行长(通常79字符)、规范的命名(变量小写加下划线
snake_case,类名大写驼峰CamelCase)。 - 写有意义的注释和文档字符串:注释解释“为什么这么做”,而非“做了什么”。为模块、类、函数编写文档字符串(
""")。 - 函数单一职责:一个函数只做一件事,并且做好。这能提高代码的可读性和可测试性。
8.2 项目结构与版本控制
- 组织项目文件:即使是小练习,也建议按功能模块分文件。一个典型的简单项目结构如下:
my_project/ ├── main.py # 程序入口 ├── utils.py # 工具函数 ├── models.py # 数据模型/类定义 ├── data/ # 数据文件目录 └── README.md # 项目说明 - 学习使用Git:尽早使用Git进行版本控制。它能帮你管理代码历史,方便回滚和协作。可以从
git init,git add,git commit基础命令开始。
8.3 下一步学习方向
- 深入标准库:Python“内置电池”非常强大。系统学习
collections,itertools,functools,os,sys,datetime,json,re等常用模块。 - 选择一个应用领域:
- Web开发:学习Flask或Django框架。
- 数据分析:学习Pandas, NumPy, Matplotlib。
- 自动化/爬虫:深入学习Requests, BeautifulSoup, Scrapy, Selenium。
- 机器学习/AI:学习Scikit-learn, TensorFlow, PyTorch。
- 参与开源项目:在GitHub上寻找感兴趣的项目,阅读源码,尝试解决简单的issue,这是提升最快的途径之一。
- 构建个人项目:想一个能解决自己或他人实际问题的点子,从设计到实现再到部署,完成一个完整的项目。
编程能力的提升没有捷径,唯有持续地思考、编码、调试和总结。这100道练习题为你搭建了一个从语法到思维的训练场。坚持完成它们,并尝试用自己的方式优化代码、解决更复杂的问题,你一定会感受到自己编程能力的实质性飞跃。动手开始写第一行代码吧,遇到问题正是学习的最佳时机。