Python 练习题(23 题)
学了那么多语法,得动手写才算真的会。这一页给 23 道精心挑选的练习题,按难度分三级——基础 10 题(变量 / 数据类型 / 条件 / 循环 / 函数)、进阶 8 题(列表推导 / 字典 / OOP / 文件)、实战 5 题(综合应用)。每题都含题目描述、提示、可折叠的参考答案。
使用建议:先别急着展开答案。读题后自己打开本地 Python 环境(或 在线 Python)试着写,卡住了再看提示,实在写不出再对照参考答案。答案不止一种,你的写法可能比参考更好——能跑通、可读性强就是好代码。
基础(10 题):变量 / 数据类型 / 条件 / 循环 / 函数
这一组覆盖最基础的语言元素,目标是用最短的代码解决一个小问题,训练"把思路翻译成代码"的能力。
第 1 题:翻转字符串
题目:写一个函数 reverse_string(s),把传入的字符串翻转过来。比如 "hello" 翻转成 "olleh"。
提示:Python 切片语法 [开始:结束:步长],步长为 -1 就是倒序;也可以用内置 reversed() 配合 "".join()。
参考答案
# 方法 1:切片 [::-1] 是最 Pythonic 的翻转
def reverse_string(s):
return s[::-1]
# 方法 2:用 reversed + join(等价写法)
def reverse_string2(s):
return "".join(reversed(s))
print(reverse_string("hello")) # olleh
print(reverse_string("Python")) # nohtyP
print(reverse_string2("你好世界")) # 界世好你第 2 题:判断素数
题目:写一个函数 is_prime(n),判断正整数 n 是否为素数(只能被 1 和自己整除)。
提示:小于 2 的都不是素数;只需检查从 2 到 sqrt(n) 的整除性——超过平方根的因子必然配对一个更小的、已经检查过的因子。
参考答案
def is_prime(n):
if n < 2:
return False
# 只需检查到 sqrt(n),超过肯定不能整除
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True
print(is_prime(2)) # True
print(is_prime(7)) # True
print(is_prime(10)) # False
print(is_prime(1)) # False第 3 题:FizzBuzz
题目:打印 1 到 15。3 的倍数打印 Fizz,5 的倍数打印 Buzz,同时是 3 和 5 的倍数打印 FizzBuzz,其余打印数字本身。
提示:if / elif / else 的判断顺序很关键——必须先判断"同时是 3 和 5 的倍数"(即 15 的倍数),否则会被前面的分支截胡。
参考答案
# 经典题:3 的倍数打印 Fizz,5 的倍数打印 Buzz,
# 同时是 3 和 5 的倍数打印 FizzBuzz,其余打印数字本身
for i in range(1, 16):
if i % 15 == 0: # 必须先判断 15(否则会被 3 或 5 截胡)
print("FizzBuzz")
elif i % 3 == 0:
print("Fizz")
elif i % 5 == 0:
print("Buzz")
else:
print(i)
# 输出:
# 1
# 2
# Fizz
# 4
# Buzz
# Fizz
# 7
# 8
# Fizz
# Buzz
# 11
# Fizz
# 13
# 14
# FizzBuzz第 4 题:求列表最大值
题目:不使用内置 max(),写一个函数 find_max(lst),返回列表中的最大值;空列表返回 None。
提示:初始化一个变量等于第一个元素,遍历剩下的依次比较、遇到更大的就更新。这是"打擂台"算法的雏形。
参考答案
def find_max(lst):
if not lst:
return None # 空列表返回 None
m = lst[0]
for x in lst[1:]: # 从第二个开始比较
if x > m:
m = x
return m
print(find_max([3, 1, 4, 1, 5, 9, 2, 6])) # 9
print(find_max([-5, -2, -9])) # -2
print(find_max([])) # None
# 提示:实际项目直接用内置 max([3,1,4,1,5,9,2,6])第 5 题:统计字符出现次数
题目:写一个函数 char_count(s),返回一个字典,key 是字符,value 是它出现的次数。比如 char_count("hello") 返回 {'h': 1, 'e': 1, 'l': 2, 'o': 1}。
提示:用 dict.get(key, default) 取值,取不到就给默认 0 再加 1;或者直接用 collections.Counter。
参考答案
def char_count(s):
count = {}
for ch in s:
count[ch] = count.get(ch, 0) + 1 # get 取不到默认 0
return count
print(char_count("hello"))
# {'h': 1, 'e': 1, 'l': 2, 'o': 1}
# 进阶:用 collections.Counter 一行搞定
from collections import Counter
print(dict(Counter("mississippi")))
# {'m': 1, 'i': 4, 's': 4, 'p': 2}第 6 题:判断回文
题目:写一个函数 is_palindrome(s),判断字符串是否回文(正读反读一样)。比如 "level"、"上海自来水来自海上" 都是回文。
提示:把字符串翻转,看是否等于原串;注意大小写差异("Level" 也应判为回文),可先 .lower() 统一。
参考答案
def is_palindrome(s):
s = s.lower() # 统一小写,大小写不影响判断
return s == s[::-1] # 正着读 == 倒着读
print(is_palindrome("level")) # True
print(is_palindrome("hello")) # False
print(is_palindrome("A man a plan a canal Panama".replace(" ", "").lower())) # True
print(is_palindrome("上海自来水来自海上")) # True第 7 题:求列表平均值
题目:写一个函数 average(lst),返回数值列表的平均值;空列表返回 0,且不能抛 ZeroDivisionError。
提示:sum(lst) / len(lst);务必先判空,len([]) == 0 会触发除零错误。
参考答案
def average(lst):
if not lst:
return 0 # 防止除以 0
return sum(lst) / len(lst)
print(average([10, 20, 30, 40])) # 25.0
print(average([100])) # 100.0
print(average([])) # 0第 8 题:计算阶乘
题目:写一个函数 factorial(n),返回 n!(n 的阶乘)。要求 factorial(0) == 1,且对负数抛 ValueError。
提示:循环写法用一个累乘变量;递归写法更贴近数学定义 n! = n * (n-1)!,但要注意递归深度。标准库 math.factorial 也可直接用。
参考答案
# 方法 1:循环
def factorial(n):
if n < 0:
raise ValueError("阶乘不接受负数")
result = 1
for i in range(1, n + 1):
result *= i
return result
# 方法 2:递归(更贴近数学定义)
def factorial_rec(n):
if n < 0:
raise ValueError("阶乘不接受负数")
return 1 if n < 2 else n * factorial_rec(n - 1)
print(factorial(5)) # 120
print(factorial(0)) # 1
print(factorial_rec(6)) # 720
# 提示:标准库也自带 math.factorial(n)第 9 题:列表去重(保持顺序)
题目:写一个函数 dedupe(lst),去掉列表中的重复元素,且保持元素首次出现的顺序。比如 [1,3,2,3,1,4,2] → [1,3,2,4]。
提示:用一个 set 记录"见过的元素",遍历时没见过就加入结果列表;直接 list(set(lst)) 会丢失顺序(集合无序)。
参考答案
def dedupe(lst):
seen = set()
result = []
for x in lst:
if x not in seen:
seen.add(x)
result.append(x)
return result
print(dedupe([1, 3, 2, 3, 1, 4, 2]))
# [1, 3, 2, 4]
# 反例:list(set(...)) 也能去重,但顺序会丢:
print(list(set([1, 3, 2, 3, 1, 4, 2]))) # 顺序不定第 10 题:九九乘法表
题目:用嵌套循环打印九九乘法表,格式 1x2=2,每行用 tab 分隔,呈下三角形状。
提示:外层循环 i 控制行(1~9),内层循环 j 控制列(只到 i);print(..., end="\\t") 不换行,一行结束 print() 换行。
参考答案
# 外层 i 控制行,内层 j 控制列;每行只打印到 j == i
for i in range(1, 10):
for j in range(1, i + 1):
print(f"{j}x{i}={i*j}", end="\t") # 用 tab 分隔,不换行
print() # 一行结束才换行
# 输出(每行用 tab 分隔):
# 1x1=1
# 1x2=2 2x2=4
# 1x3=3 2x3=6 3x3=9
# ...一直到 9x9=81进阶(8 题):列表推导 / 字典 / OOP / 文件
这一组开始组合多个知识点——用推导式写出更紧凑的代码、用类组织数据、读写真实文件、用装饰器给函数加功能。做完了你会对 Python 的"表达力"有直观感受。
第 11 题:词频统计(文件读取 + 字典排序)
题目:给定一段英文文本,统计每个单词的出现次数,按频次降序输出 Top 5。提示:实际从文件读,这里用内联文本演示。
提示:re.findall(r"[a-z]+", text.lower()) 提取单词并统一小写;collections.Counter 自动计数,.most_common(5) 自动排序。
参考答案
# wordcount.py — 统计文本中每个单词的出现次数,按频次降序输出 Top N
import re
from collections import Counter
def word_count(text):
# 用正则提取所有英文单词,统一转小写避免 The/the 分开计数
words = re.findall(r"[a-z]+", text.lower())
return Counter(words) # Counter 是 dict 子类,自动计数
# 模拟文本(实际项目用 open("article.txt", encoding="utf-8").read())
text = """
The quick brown fox jumps over the lazy dog.
The dog was not amused, but the fox just laughed.
"""
counter = word_count(text)
print("Top 5 高频词:")
for word, cnt in counter.most_common(5): # most_common 自动排序
print(f" {word}: {cnt}")
# 输出:
# Top 5 高频词:
# the: 4
# dog: 2
# fox: 2
# quick: 1
# brown: 1第 12 题:学生类 + 成绩管理(OOP)
题目:定义 Student 类(姓名 + 多科成绩 dict,能算均分)和 ClassRoom 类(能添加学生、按均分排名)。
提示:__init__ 存数据,__repr__ 控制 print 显示;sorted 配合 key=lambda s: s.average() 排序,reverse=True 降序。
参考答案
class Student:
def __init__(self, name, scores):
self.name = name
self.scores = scores # dict: {"数学": 90, "语文": 85}
def average(self):
return sum(self.scores.values()) / len(self.scores)
def __repr__(self): # 控制 print 时的显示
return f"<Student {self.name}, 均分 {self.average():.1f}>"
class ClassRoom:
def __init__(self):
self.students = []
def add(self, student):
self.students.append(student)
def rank(self): # 按均分降序
return sorted(self.students, key=lambda s: s.average(), reverse=True)
cls = ClassRoom()
cls.add(Student("小明", {"数学": 90, "语文": 80}))
cls.add(Student("小红", {"数学": 95, "语文": 88}))
cls.add(Student("小刚", {"数学": 70, "语文": 100}))
print("成绩排名:")
for i, s in enumerate(cls.rank(), 1):
print(f" {i}. {s}")
# 输出:
# 成绩排名:
# 1. <Student 小红, 均分 91.5>
# 2. <Student 小明, 均分 85.0>
# 3. <Student 小刚, 均分 85.0>第 13 题:CSV 解析(标准库 csv)
题目:读取一段 CSV(姓名,年龄,城市),筛出年龄 ≥ 28 的人并打印。不要自己 split 逗号,用标准库 csv 模块。
提示:csv.DictReader 把每行读成 dict,首行自动当表头;自己 split 会处理不了字段里有逗号(被引号包裹)的情况。
参考答案
import csv
from io import StringIO
# 模拟 CSV 内容(实际用 with open("data.csv", encoding="utf-8") as f)
csv_text = "姓名,年龄,城市\n张三,28,北京\n李四,35,上海\n王五,22,广州"
# DictReader 把每行读成 dict,用首行做 key
reader = csv.DictReader(StringIO(csv_text))
# 筛选年龄 >= 28 的人
adults = [row for row in reader if int(row["年龄"]) >= 28]
for r in adults:
print(f"{r['姓名']} / {r['年龄']} 岁 / {r['城市']}")
# 输出:
# 张三 / 28 岁 / 北京
# 李四 / 35 岁 / 上海第 14 题:装饰器计时器
题目:写一个 @timer 装饰器,被装饰的函数调用结束后自动打印执行耗时。要求不改变原函数的返回值,且保留原函数名。
提示:装饰器是"接收函数返回函数"的高阶函数;内层 wrapper 用 *args, **kwargs 透传参数,time.perf_counter() 计时;@wraps(func) 保留元信息。
参考答案
import time
from functools import wraps
def timer(func):
@wraps(func) # 保留原函数名和文档字符串
def wrapper(*args, **kwargs):
start = time.perf_counter()
result = func(*args, **kwargs)
elapsed = time.perf_counter() - start
print(f"[timer] {func.__name__} 耗时 {elapsed:.6f} 秒")
return result
return wrapper
@timer # 等价于 slow_sum = timer(slow_sum)
def slow_sum(n):
"""从 0 加到 n-1"""
return sum(range(n))
print(slow_sum(1_000_000))
# 输出:
# [timer] slow_sum 耗时 0.031xxx 秒
# 499999500000
# 提示:@wraps 让 slow_sum.__name__ 仍是 'slow_sum',不会变成 'wrapper'第 15 题:列表推导(乘法表 + 筛素数)
题目:用一行列表推导完成三件事:(a) 生成 9×9 乘法表二维列表;(b) 筛出 100 以内的全部素数;(c) 把列表转成 {值: 索引} 的反查字典。
提示:嵌套推导 [[i*j for j in ...] for i in ...];筛素数配合 all(...) 判断无整除因子;反查表用字典推导 {v: i for i, v in enumerate(...)}。
参考答案
# 1. 嵌套列表推导:生成 9x9 乘法表(二维列表)
table = [[i * j for j in range(1, 10)] for i in range(1, 10)]
print(table[4][4]) # 第 5 行第 5 列: 5*5 = 25
# 2. 列表推导 + all():筛出 100 以内的素数
n = 100
primes = [x for x in range(2, n + 1)
if all(x % d != 0 for d in range(2, int(x ** 0.5) + 1))]
print(primes)
# [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
# 3. 字典推导:把列表转成 {值: 索引} 反查表
idx = {v: i for i, v in enumerate(["a", "b", "c"])}
print(idx) # {'a': 0, 'b': 1, 'c': 2}第 16 题:二分查找
题目:写一个函数 binary_search(sorted_list, target),在升序列表里找目标值,返回下标;找不到返回 -1。要求时间复杂度 O(log n)。
提示:维护 lo / hi 两个指针,每次取中点 mid = (lo + hi) // 2,比较中点与目标,淘汰一半区间;标准库 bisect 也能做。
参考答案
def binary_search(sorted_list, target):
"""在升序列表里找 target,返回下标;找不到返回 -1"""
lo, hi = 0, len(sorted_list) - 1
while lo <= hi:
mid = (lo + hi) // 2
if sorted_list[mid] == target:
return mid
elif sorted_list[mid] < target:
lo = mid + 1 # 目标在右半边
else:
hi = mid - 1 # 目标在左半边
return -1
data = [1, 3, 5, 7, 9, 11, 13, 15]
print(binary_search(data, 7)) # 3
print(binary_search(data, 9)) # 4
print(binary_search(data, 10)) # -1(不存在)
# 提示:标准库 bisect.bisect_left 也能做二分,而且更快第 17 题:按 key 分组(setdefault)
题目:写一个函数 group_by(items, key_func),把列表按某个 key 归类成 {key: [items...]} 的字典。比如把员工按部门分组。
提示:遍历时用 dict.setdefault(key, []).append(item)——key 不存在就先放个空列表,再 append。这是处理"字典里嵌列表"的惯用法。
参考答案
def group_by(items, key_func):
groups = {}
for item in items:
key = key_func(item)
groups.setdefault(key, []).append(item) # key 不存在就先放空列表
return groups
users = [
{"name": "小明", "dept": "技术部"},
{"name": "小红", "dept": "市场部"},
{"name": "小刚", "dept": "技术部"},
{"name": "小丽", "dept": "市场部"},
{"name": "小强", "dept": "技术部"},
]
by_dept = group_by(users, lambda u: u["dept"])
for dept, members in by_dept.items():
print(f"{dept}: {[m['name'] for m in members]}")
# 输出:
# 技术部: ['小明', '小刚', '小强']
# 市场部: ['小红', '小丽']第 18 题:JSON 配置文件读写(文件 + 字典)
题目:写 load_config() 和 save_config(cfg) 两个函数,把配置存成 JSON 文件。要求:文件不存在时返回空 dict;中文不被转成 \uXXXX。
提示:json.load / json.dump 读写;ensure_ascii=False 让中文原样写入;indent=2 让文件可读;先 os.path.exists 判存在。
参考答案
import json
import os
CONFIG_FILE = "config.json"
def load_config():
"""读取配置;文件不存在则返回空 dict"""
if not os.path.exists(CONFIG_FILE):
return {}
with open(CONFIG_FILE, "r", encoding="utf-8") as f:
return json.load(f)
def save_config(cfg):
"""保存配置;ensure_ascii=False 让中文原样写入"""
with open(CONFIG_FILE, "w", encoding="utf-8") as f:
json.dump(cfg, f, ensure_ascii=False, indent=2)
# 用法:读出来 → 改一项 → 写回去
cfg = load_config()
cfg["theme"] = "dark"
cfg["font_size"] = 14
save_config(cfg)
print("已保存:", cfg)
# config.json 文件内容:
# {
# "theme": "dark",
# "font_size": 14
# }实战(5 题):综合应用
这一组每题都会综合用到多个知识点——函数、异常处理、递归、正则、交互输入——做出一个接近真实场景的小程序。建议每题都完整跑一遍,再想想怎么扩展。
第 19 题:简易计算器(函数 + 异常处理)
题目:实现一个简易计算器,支持 + - * / 四则运算。要求:除数为 0 时不崩溃(给出友好提示);输入格式错误时能恢复继续;做一个交互式版本。
提示:核心 calc(a, op, b) 函数用 if/elif 分派运算符,除零抛 ZeroDivisionError;交互主循环用 try/except 接住 IndexError(格式错)和 ValueError(非数字)。
参考答案
def calc(a, op, b):
if op == "+":
return a + b
elif op == "-":
return a - b
elif op == "*":
return a * b
elif op == "/":
if b == 0:
raise ZeroDivisionError("除数不能为 0")
return a / b
else:
raise ValueError(f"不支持的运算符: {op}")
def main():
"""交互式计算器,输入格式:3 + 5;输入 q 退出"""
print("简易计算器(示例:3 + 5,输入 q 退出)")
while True:
s = input(">>> ").strip()
if s.lower() == "q":
print("再见!")
break
try:
parts = s.split()
a, op, b = float(parts[0]), parts[1], float(parts[2])
print(f"= {calc(a, op, b)}")
except (IndexError, ValueError):
print("格式错误,请按 '数字 运算符 数字' 输入")
except ZeroDivisionError as e:
print(f"错误: {e}")
# 非交互演示(直接调用 calc):
print(calc(3, "+", 5)) # 8.0
print(calc(10, "/", 4)) # 2.5
print(calc(2, "*", 9)) # 18.0
# 想用交互版,取消下一行的注释:
# main()第 20 题:矩阵转置
题目:写一个函数 transpose(matrix),把二维列表(矩阵)转置——行变列、列变行。比如 2×3 矩阵转成 3×2。
提示:最 Pythonic 的写法是 [list(row) for row in zip(*matrix)];* 把矩阵的每一行"拆"成 zip 的多个参数,zip 自动按列打包。也可用嵌套列表推导手写。
参考答案
# 方法 1:zip + 解包,最 Pythonic 的转置写法
def transpose(matrix):
return [list(row) for row in zip(*matrix)]
# 方法 2:嵌套 for,理解原理
def transpose_verbose(matrix):
if not matrix:
return []
rows, cols = len(matrix), len(matrix[0])
return [[matrix[r][c] for r in range(rows)] for c in range(cols)]
m = [
[1, 2, 3],
[4, 5, 6],
]
print("原矩阵:")
for row in m:
print(row)
print("转置后:")
for row in transpose(m):
print(row)
# 输出:
# 原矩阵:
# [1, 2, 3]
# [4, 5, 6]
# 转置后:
# [1, 4]
# [2, 5]
# [3, 6]
# 提示:zip(*m) 把每一列打包,妙在 * 把行"拆开"当多个参数第 21 题:递归斐波那契 + 记忆化
题目:实现斐波那契数列 fib(n)(fib(0)=0, fib(1)=1, fib(n)=fib(n-1)+fib(n-2))。先写朴素递归,再加记忆化,对比两者在 n=35 时的性能差距。
提示:朴素递归会重复计算同一 n 上千万次;@functools.lru_cache(maxsize=None) 一行就能自动记忆化;也可手写 memo 字典理解原理。
参考答案
from functools import lru_cache
# 1. 朴素递归:重复计算爆炸,n=35 就明显卡
def fib_slow(n):
if n < 2:
return n
return fib_slow(n - 1) + fib_slow(n - 2)
# 2. lru_cache 装饰器一行实现记忆化(推荐)
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n - 1) + fib(n - 2)
# 3. 手写记忆化字典(理解原理)
def fib_memo(n, memo=None):
if memo is None:
memo = {0: 0, 1: 1}
if n not in memo:
memo[n] = fib_memo(n - 1, memo) + fib_memo(n - 2, memo)
return memo[n]
print(fib(10)) # 55
print(fib(50)) # 12586269025(朴素版根本跑不出来)
print(fib_memo(35)) # 9227465
# 提示:朴素递归 fib_slow(35) 约 2900 万次调用;记忆化后每个 n 只算一次第 22 题:密码强度检查
题目:写一个函数 password_strength(pwd),根据长度、是否含大小写字母、数字、特殊符号,给出"弱 / 中 / 强"评级,并返回改进建议。
提示:用 re.search 检查各类字符的存在性(如 r"[A-Z]"、r"\\d");把 5 条规则各算 1 分,2 分以下弱、3-4 分中、5 分强;收集未达标的规则作为建议。
参考答案
import re
def password_strength(pwd):
"""返回 (等级, 缺失项列表)。等级:弱 / 中 / 强"""
checks = [
(len(pwd) >= 8, "长度至少 8 位"),
(re.search(r"[a-z]", pwd) is not None, "包含小写字母"),
(re.search(r"[A-Z]", pwd) is not None, "包含大写字母"),
(re.search(r"\d", pwd) is not None, "包含数字"),
(re.search(r"[!@#$%^&*]", pwd) is not None, "包含特殊符号"),
]
score = sum(1 for ok, _ in checks if ok)
misses = [tip for ok, tip in checks if not ok]
level = "弱" if score <= 2 else ("中" if score <= 3 else "强")
return level, misses
for pwd in ["123", "abcdefgh", "Abc12345", "Abc!2345xyz"]:
level, misses = password_strength(pwd)
extra = f"(建议: {'; '.join(misses)})" if misses else ""
print(f"'{pwd}' -> {level} {extra}")
# 输出:
# '123' -> 弱 (建议: 长度至少 8 位; 包含小写字母; 包含大写字母; 包含特殊符号)
# 'abcdefgh' -> 中 (建议: 包含大写字母; 包含数字; 包含特殊符号)
# 'Abc12345' -> 中 (建议: 包含特殊符号)
# 'Abc!2345xyz' -> 强第 23 题:简易 REPL(交互式命令行)
题目:实现一个简易 REPL(Read-Eval-Print Loop),支持两种输入:(a) 变量 = 表达式 赋值;(b) 直接输入表达式求值。变量要能被后续表达式引用。输入 :q 退出。
提示:维护一个 env 字典存变量;用受限的 eval(expr, {"__builtins__": {}}, env) 求值(禁用内置函数更安全);line.split("=", 1) 拆赋值,注意排除 ==(比较运算)。
参考答案
def repl():
"""简易 REPL:支持 '变量 = 表达式' 赋值,以及直接输入表达式求值。
受限 eval:禁用所有内置函数,只允许访问当前 env 里的变量。"""
env = {} # 变量表
def evaluate(expr):
try:
return eval(expr, {"__builtins__": {}}, env)
except Exception as e:
return f"错误: {e}"
print("简易 REPL(输入 :q 退出)")
while True:
line = input(">>> ").strip()
if not line:
continue
if line == ":q":
print("再见!")
break
if "=" in line and not line.startswith("=="):
name, expr = line.split("=", 1)
name, expr = name.strip(), expr.strip()
if name.isidentifier():
env[name] = evaluate(expr)
print(f"{name} = {env[name]}")
else:
print(f"非法变量名: {name}")
else:
print(evaluate(line))
# 非交互演示(说明原理):env 就是个普通 dict
env = {}
env["x"] = eval("10", {"__builtins__": {}}, env)
env["y"] = eval("x * 2 + 5", {"__builtins__": {}}, env) # 能读到刚赋值的 x
print(env) # {'x': 10, 'y': 25}
print(env["y"]) # 25
# 想用交互版,取消下一行注释:
# repl()练习建议
不要只看答案。把每道题在本地或在线环境亲手敲一遍,改一改输入试试边界情况(空列表、负数、超长字符串)。编程是手艺活,键盘上练出来的肌肉记忆比眼睛看十遍都管用。
试着扩展:做完第 12 题学生管理,能不能加上"按单科排名""导出成绩单"?做完第 19 题计算器,能不能加上幂运算和括号?做完第 22 题密码检查,能不能检查"不能含连续 3 个相同字符"?每个扩展都是一次小型的真实开发。
更多练习资源:刷算法去 LeetCode / Codewars;做小项目去 GitHub 找灵感;遇到不懂的先查 官方文档(有中文版)。
← 上一篇 Python 实战项目
返回 Python 教程目录