Python(二十五) 列表、字典、集合推导式详解
1. 什么是推导式
推导式是 Python 中一种非常常用的语法。
它可以用简洁的代码,根据已有数据快速生成新的数据。
通俗地说:
推导式就是把 for 循环生成数据的过程,压缩成一行来写。
例如,我们想生成一个列表,里面保存 1 到 5 的平方。
普通写法:
nums = []
for x in range(1, 6):
nums.append(x * x)
print(nums)
输出:
[1, 4, 9, 16, 25]
使用列表推导式:
nums = [x * x for x in range(1, 6)]
print(nums)
输出:
[1, 4, 9, 16, 25]
两段代码结果一样。
推导式的好处是:
- 写法简洁。
- 逻辑清楚。
- 常用于生成列表、字典、集合。
2. 推导式有哪些类型
Python 中常见的推导式主要有三种:
| 类型 | 写法 | 生成结果 |
|---|---|---|
| 列表推导式 | [表达式 for 变量 in 可迭代对象] |
list 列表 |
| 字典推导式 | {键表达式: 值表达式 for 变量 in 可迭代对象} |
dict 字典 |
| 集合推导式 | {表达式 for 变量 in 可迭代对象} |
set 集合 |
另外还有一种很像推导式的写法,叫生成器表达式:
(表达式 for 变量 in 可迭代对象)
它不是元组推导式,而是生成器表达式。
本篇重点讲:
- 列表推导式
- 字典推导式
- 集合推导式
3. 先理解几个基础概念
3.1 什么是可迭代对象
可迭代对象简单理解就是:可以被 for 循环遍历的数据。
常见可迭代对象:
list # 列表
tuple # 元组
dict # 字典
set # 集合
str # 字符串
range # range 对象
例如:
for x in [1, 2, 3]:
print(x)
列表可以被 for 循环遍历,所以列表是可迭代对象。
再比如:
for ch in "abc":
print(ch)
字符串也可以被遍历,所以字符串也是可迭代对象。
3.2 什么是表达式
表达式就是可以计算出结果的代码。
例如:
x
x * 2
x + 10
x.upper()
str(x)
这些都可以作为推导式中的表达式。
3.3 推导式的基本思路
推导式一般可以按下面的顺序理解:
从一个可迭代对象中,依次取出元素,
对元素进行处理,
再把处理结果放入新的列表、字典或集合中。
4. 列表推导式
列表推导式用于快速创建列表。
4.1 基本语法
[表达式 for 变量 in 可迭代对象]
例如:
nums = [x for x in range(1, 6)]
print(nums)
输出:
[1, 2, 3, 4, 5]
这段代码可以拆成普通循环:
nums = []
for x in range(1, 6):
nums.append(x)
print(nums)
4.2 生成数字列表
nums = [x for x in range(10)]
print(nums)
输出:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
4.3 对元素进行计算
生成 1 到 5 的平方:
squares = [x * x for x in range(1, 6)]
print(squares)
输出:
[1, 4, 9, 16, 25]
普通循环写法:
squares = []
for x in range(1, 6):
squares.append(x * x)
print(squares)
4.4 对字符串进行处理
把所有单词转换成大写:
words = ["python", "java", "c++"]
result = [word.upper() for word in words]
print(result)
输出:
['PYTHON', 'JAVA', 'C++']
去掉字符串两边的空格:
names = [" 张三 ", " 李四", "王五 "]
result = [name.strip() for name in names]
print(result)
输出:
['张三', '李四', '王五']
4.5 加上筛选条件
语法:
[表达式 for 变量 in 可迭代对象 if 条件]
筛选偶数:
nums = [1, 2, 3, 4, 5, 6]
evens = [x for x in nums if x % 2 == 0]
print(evens)
输出:
[2, 4, 6]
普通循环写法:
nums = [1, 2, 3, 4, 5, 6]
evens = []
for x in nums:
if x % 2 == 0:
evens.append(x)
print(evens)
4.6 筛选长度大于 3 的字符串
words = ["hi", "python", "java", "ok"]
result = [word for word in words if len(word) > 3]
print(result)
输出:
['python', 'java']
4.7 多个筛选条件
筛选大于 10 且是偶数的数字:
nums = [5, 8, 12, 15, 20, 23]
result = [x for x in nums if x > 10 if x % 2 == 0]
print(result)
输出:
[12, 20]
也可以写成:
nums = [5, 8, 12, 15, 20, 23]
result = [x for x in nums if x > 10 and x % 2 == 0]
print(result)
输出:
[12, 20]
教学中推荐第二种写法,因为更直观。
4.8 使用 if...else
如果需要根据条件给出不同结果,可以使用 if...else。
语法:
[值1 if 条件 else 值2 for 变量 in 可迭代对象]
例如,把偶数标记为 "偶数",奇数标记为 "奇数":
nums = [1, 2, 3, 4, 5]
result = ["偶数" if x % 2 == 0 else "奇数" for x in nums]
print(result)
输出:
['奇数', '偶数', '奇数', '偶数', '奇数']
再比如,及格显示 "通过",不及格显示 "不通过":
scores = [90, 58, 76, 45]
result = ["通过" if score >= 60 else "不通过" for score in scores]
print(result)
输出:
['通过', '不通过', '通过', '不通过']
4.9 if 筛选和 if...else 的区别
这两个写法很容易混淆。
写法一:只筛选
[x for x in nums if x > 0]
意思是:
只保留大于 0 的 x。
写法二:二选一处理
[x if x > 0 else 0 for x in nums]
意思是:
如果 x 大于 0,就保留 x;
否则使用 0。
示例:
nums = [-2, -1, 0, 1, 2]
result1 = [x for x in nums if x > 0]
result2 = [x if x > 0 else 0 for x in nums]
print(result1)
print(result2)
输出:
[1, 2]
[0, 0, 0, 1, 2]
区别总结:
| 写法 | 含义 | 结果数量是否可能变少 |
|---|---|---|
[x for x in nums if 条件] |
筛选数据 | 可能变少 |
[值1 if 条件 else 值2 for x in nums] |
对每个数据做二选一处理 | 数量不变 |
4.10 嵌套循环列表推导式
列表推导式中可以写多个 for。
例如,生成两个列表元素的所有组合:
colors = ["红", "蓝"]
sizes = ["S", "M", "L"]
result = [(color, size) for color in colors for size in sizes]
print(result)
输出:
[('红', 'S'), ('红', 'M'), ('红', 'L'), ('蓝', 'S'), ('蓝', 'M'), ('蓝', 'L')]
等价于:
colors = ["红", "蓝"]
sizes = ["S", "M", "L"]
result = []
for color in colors:
for size in sizes:
result.append((color, size))
print(result)
推导式中的 for 顺序和普通循环顺序一致。
[(color, size) for color in colors for size in sizes]
对应:
for color in colors:
for size in sizes:
...
4.11 展平二维列表
把二维列表变成一维列表:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
result = [num for row in matrix for num in row]
print(result)
输出:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
等价于:
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
result = []
for row in matrix:
for num in row:
result.append(num)
print(result)
4.12 嵌套循环加条件
生成所有乘积大于 10 的组合:
a = [1, 2, 3, 4]
b = [3, 4, 5]
result = [(x, y) for x in a for y in b if x * y > 10]
print(result)
输出:
[(3, 4), (3, 5), (4, 3), (4, 4), (4, 5)]
虽然可以这样写,但如果逻辑太复杂,普通循环更适合教学和维护。
4.13 配合 enumerate()
enumerate() 可以同时得到下标和元素。
names = ["张三", "李四", "王五"]
result = [f"{index}: {name}" for index, name in enumerate(names)]
print(result)
输出:
['0: 张三', '1: 李四', '2: 王五']
如果希望编号从 1 开始:
names = ["张三", "李四", "王五"]
result = [f"{index}: {name}" for index, name in enumerate(names, start=1)]
print(result)
输出:
['1: 张三', '2: 李四', '3: 王五']
4.14 配合 zip()
zip() 可以把多个可迭代对象中对应位置的元素组合起来。
names = ["张三", "李四", "王五"]
scores = [90, 85, 78]
result = [f"{name}: {score}" for name, score in zip(names, scores)]
print(result)
输出:
['张三: 90', '李四: 85', '王五: 78']
5. 字典推导式
字典推导式用于快速创建字典。
5.1 基本语法
{键表达式: 值表达式 for 变量 in 可迭代对象}
例如,创建数字和平方的对应关系:
squares = {x: x * x for x in range(1, 6)}
print(squares)
输出:
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
普通循环写法:
squares = {}
for x in range(1, 6):
squares[x] = x * x
print(squares)
5.2 从两个列表创建字典
names = ["张三", "李四", "王五"]
scores = [90, 85, 78]
result = {name: score for name, score in zip(names, scores)}
print(result)
输出:
{'张三': 90, '李四': 85, '王五': 78}
这里 zip(names, scores) 会依次产生:
("张三", 90)
("李四", 85)
("王五", 78)
5.3 遍历字典创建新字典
如果要遍历字典的键和值,一般使用 .items()。
scores = {"张三": 90, "李四": 85, "王五": 78}
result = {name: score + 5 for name, score in scores.items()}
print(result)
输出:
{'张三': 95, '李四': 90, '王五': 83}
5.4 筛选字典中的数据
筛选成绩大于等于 80 的学生:
scores = {"张三": 90, "李四": 58, "王五": 78, "赵六": 88}
passed = {name: score for name, score in scores.items() if score >= 80}
print(passed)
输出:
{'张三': 90, '赵六': 88}
普通循环写法:
scores = {"张三": 90, "李四": 58, "王五": 78, "赵六": 88}
passed = {}
for name, score in scores.items():
if score >= 80:
passed[name] = score
print(passed)
5.5 修改字典中的值
给所有学生成绩加 10 分:
scores = {"张三": 70, "李四": 80, "王五": 90}
new_scores = {name: score + 10 for name, score in scores.items()}
print(new_scores)
输出:
{'张三': 80, '李四': 90, '王五': 100}
5.6 修改字典中的键
把所有姓名前面加上 "学生-":
scores = {"张三": 90, "李四": 85}
result = {f"学生-{name}": score for name, score in scores.items()}
print(result)
输出:
{'学生-张三': 90, '学生-李四': 85}
5.7 键和值互换
scores = {"张三": 90, "李四": 85, "王五": 78}
result = {score: name for name, score in scores.items()}
print(result)
输出:
{90: '张三', 85: '李四', 78: '王五'}
注意:如果原字典中的值有重复,互换后会丢失数据。
例如:
scores = {"张三": 90, "李四": 90, "王五": 78}
result = {score: name for name, score in scores.items()}
print(result)
可能输出:
{90: '李四', 78: '王五'}
因为字典的键不能重复。
当两个学生的成绩都是 90,互换后键都是 90,后面的值会覆盖前面的值。
5.8 使用 enumerate() 创建编号字典
names = ["张三", "李四", "王五"]
result = {index: name for index, name in enumerate(names, start=1)}
print(result)
输出:
{1: '张三', 2: '李四', 3: '王五'}
5.9 使用 if...else 处理值
根据成绩生成是否通过:
scores = {"张三": 90, "李四": 58, "王五": 76}
result = {name: "通过" if score >= 60 else "不通过" for name, score in scores.items()}
print(result)
输出:
{'张三': '通过', '李四': '不通过', '王五': '通过'}
5.10 字典推导式中的键必须可哈希
字典的键必须是不可变、可哈希的数据。
可以作为键的常见类型:
int
float
str
tuple
不能作为键的常见类型:
list
dict
set
错误示例:
data = [[1, 2], [3, 4]]
result = {item: len(item) for item in data} # 错误
因为 item 是列表,列表不能作为字典的键。
可以改成元组:
data = [[1, 2], [3, 4]]
result = {tuple(item): len(item) for item in data}
print(result)
输出:
{(1, 2): 2, (3, 4): 2}
6. 集合推导式
集合推导式用于快速创建集合。
集合的特点是:
无序、不重复。
6.1 基本语法
{表达式 for 变量 in 可迭代对象}
例如,生成平方集合:
squares = {x * x for x in range(1, 6)}
print(squares)
输出可能是:
{1, 4, 9, 16, 25}
普通循环写法:
squares = set()
for x in range(1, 6):
squares.add(x * x)
print(squares)
6.2 自动去重
集合推导式会自动去掉重复元素。
nums = [1, 2, 2, 3, 3, 3]
result = {x for x in nums}
print(result)
输出:
{1, 2, 3}
这和 set(nums) 的效果类似。
nums = [1, 2, 2, 3, 3, 3]
result = set(nums)
print(result)
输出:
{1, 2, 3}
6.3 筛选数据并去重
筛选偶数,并自动去重:
nums = [1, 2, 2, 3, 4, 4, 5, 6]
evens = {x for x in nums if x % 2 == 0}
print(evens)
输出:
{2, 4, 6}
6.4 提取字符串中的不同字符
text = "banana"
chars = {ch for ch in text}
print(chars)
输出可能是:
{'b', 'a', 'n'}
因为集合无序,所以输出顺序不固定。
6.5 统一大小写后去重
words = ["Python", "python", "JAVA", "java"]
result = {word.lower() for word in words}
print(result)
输出:
{'python', 'java'}
6.6 集合推导式加 if...else
把偶数保留,奇数改成 0,再放入集合:
nums = [1, 2, 3, 4, 5]
result = {x if x % 2 == 0 else 0 for x in nums}
print(result)
输出:
{0, 2, 4}
注意:多个奇数都会变成 0,集合会自动去重,所以只保留一个 0。
6.7 集合推导式和字典推导式的区别
集合推导式:
{x for x in range(3)}
结果:
{0, 1, 2}
字典推导式:
{x: x * x for x in range(3)}
结果:
{0: 0, 1: 1, 2: 4}
区别在于:
集合推导式只有一个表达式。
字典推导式有 key: value。
6.8 空集合不能写成 {}
空集合必须写成:
s = set()
不能写成:
s = {}
因为 {} 表示空字典。
print(type({}))
print(type(set()))
输出:
<class 'dict'>
<class 'set'>
7. 三种推导式对比
假设有一个列表:
nums = [1, 2, 3, 4]
7.1 生成列表
result = [x * x for x in nums]
print(result)
输出:
[1, 4, 9, 16]
7.2 生成字典
result = {x: x * x for x in nums}
print(result)
输出:
{1: 1, 2: 4, 3: 9, 4: 16}
7.3 生成集合
result = {x * x for x in nums}
print(result)
输出:
{16, 1, 4, 9}
输出顺序可能不同,因为集合无序。
7.4 对比表
| 类型 | 外层符号 | 是否有 key:value | 是否允许重复 | 是否有序 |
|---|---|---|---|---|
| 列表推导式 | [] |
否 | 允许重复 | 有序 |
| 字典推导式 | {} |
是 | 键不能重复 | 有序保存插入顺序 |
| 集合推导式 | {} |
否 | 不允许重复 | 无序 |
注意:
字典在 Python 3.7 及以后会保留插入顺序。
但字典的重点仍然是通过键查找值。
8. 推导式的执行顺序
很多初学者看到推导式会不知道从哪里开始看。
建议从 for 开始读。
例如:
result = [x * 2 for x in range(1, 4)]
阅读顺序:
for x in range(1, 4) 先依次取出 1、2、3
然后执行 x * 2
最后把结果放入列表
所以结果是:
[2, 4, 6]
再看带条件的:
result = [x * 2 for x in range(1, 6) if x % 2 == 0]
阅读顺序:
1. 从 range(1, 6) 中取出 x
2. 判断 x % 2 == 0
3. 如果条件成立,就计算 x * 2
4. 把结果放入列表
结果:
[4, 8]
9. 推导式中的 if 位置
推导式中 if 的位置非常重要。
9.1 过滤用的 if 放在后面
result = [x for x in range(10) if x % 2 == 0]
意思是:
只保留偶数。
9.2 if...else 放在前面
result = ["偶数" if x % 2 == 0 else "奇数" for x in range(5)]
意思是:
每个数都处理,只是处理结果不同。
9.3 常见错误
错误写法:
result = [x for x in range(5) if x % 2 == 0 else 0]
这是错误的。
如果有 else,应该写在 for 前面的表达式中。
正确写法:
result = [x if x % 2 == 0 else 0 for x in range(5)]
10. 推导式和普通 for 循环的选择
推导式不是必须使用的。
它适合处理简单、清晰的数据转换。
10.1 适合使用推导式的情况
适合:
nums = [1, 2, 3, 4]
result = [x * 2 for x in nums]
适合:
scores = {"张三": 90, "李四": 58}
result = {name: score for name, score in scores.items() if score >= 60}
适合:
words = ["Python", "python", "Java"]
result = {word.lower() for word in words}
这些代码逻辑都比较短,推导式很清楚。
10.2 不适合使用推导式的情况
如果逻辑很复杂,不推荐强行使用推导式。
例如:
result = [
"优秀" if score >= 90 else "良好" if score >= 80 else "及格" if score >= 60 else "不及格"
for score in scores
]
虽然这段代码可以运行,但可读性不太好。
更推荐写成普通循环:
result = []
for score in scores:
if score >= 90:
result.append("优秀")
elif score >= 80:
result.append("良好")
elif score >= 60:
result.append("及格")
else:
result.append("不及格")
教学时可以这样总结:
简单逻辑用推导式。
复杂逻辑用普通 for 循环。
11. 推导式和生成器表达式
圆括号写法不是元组推导式。
result = (x * x for x in range(5))
print(result)
输出类似:
<generator object <genexpr> at 0x...>
这叫生成器表达式。
生成器不会一次性生成所有数据,而是用到一个生成一个。
11.1 创建元组要使用 tuple()
如果想用类似推导式的方式创建元组,要写:
result = tuple(x * x for x in range(5))
print(result)
输出:
(0, 1, 4, 9, 16)
不能认为下面是元组推导式:
result = (x * x for x in range(5))
它是生成器表达式。
12. 推导式中的变量作用域
在 Python 3 中,推导式内部的变量不会影响外部同名变量。
x = 100
result = [x for x in range(3)]
print(result)
print(x)
输出:
[0, 1, 2]
100
外面的 x 仍然是 100。
虽然如此,教学和实际开发中仍然建议变量名写清楚。
例如:
scores = [90, 85, 78]
result = [score + 5 for score in scores]
比下面更清楚:
scores = [90, 85, 78]
result = [x + 5 for x in scores]
13. 推导式中的常见注意事项
13.1 不要为了简短牺牲可读性
推导式不是越短越好。
如果一行写得太复杂,学生和同事都很难读懂。
不推荐:
result = [x * y for x in range(10) for y in range(10) if x % 2 == 0 if y % 3 == 0]
如果逻辑复杂,可以写成普通循环。
13.2 不要在推导式中做复杂副作用操作
推导式主要用于生成新数据。
不推荐用它来做打印、写文件、修改外部变量等操作。
不推荐:
[print(x) for x in range(5)]
更推荐:
for x in range(5):
print(x)
因为打印的重点是执行动作,不是生成列表。
13.3 字典推导式要注意键重复
data = ["apple", "ant", "banana", "book"]
result = {word[0]: word for word in data}
print(result)
可能输出:
{'a': 'ant', 'b': 'book'}
原因是:
apple 和 ant 的键都是 'a'。
banana 和 book 的键都是 'b'。
后面的值覆盖了前面的值。
字典的键不能重复。
13.4 集合推导式会自动去重
nums = [1, 1, 2, 2, 3]
result = {x for x in nums}
print(result)
输出:
{1, 2, 3}
如果你需要保留重复元素,就不要用集合推导式。
应该使用列表推导式:
nums = [1, 1, 2, 2, 3]
result = [x for x in nums]
print(result)
输出:
[1, 1, 2, 2, 3]
13.5 集合是无序的,不要依赖输出顺序
result = {x for x in [3, 1, 2]}
print(result)
输出顺序不一定是你写入的顺序。
如果需要有顺序的结果,请使用列表推导式。
13.6 空集合不能用 {}
s = {}
这是空字典,不是空集合。
空集合要写:
s = set()
13.7 不要一边遍历字典一边修改原字典
不推荐:
scores = {"张三": 90, "李四": 58}
for name in scores:
if scores[name] < 60:
del scores[name]
这样可能导致运行错误。
如果要筛选字典,推荐创建一个新字典:
scores = {"张三": 90, "李四": 58}
new_scores = {name: score for name, score in scores.items() if score >= 60}
print(new_scores)
输出:
{'张三': 90}
13.8 推导式会创建新对象
列表推导式会创建新列表。
nums = [1, 2, 3]
result = [x * 2 for x in nums]
print(nums)
print(result)
输出:
[1, 2, 3]
[2, 4, 6]
原列表 nums 没有被修改。
字典推导式和集合推导式也一样,通常是创建新对象。
13.9 数据量特别大时要注意内存
列表推导式会一次性生成完整列表。
result = [x for x in range(10000000)]
如果数据量非常大,可能占用较多内存。
这种情况下可以考虑生成器表达式:
result = (x for x in range(10000000))
生成器不会一次性创建所有数据。
初学阶段先掌握列表、字典、集合推导式即可。
14. 综合案例
14.1 批量清洗姓名
需求:
去掉姓名两边空格,并过滤空字符串。
代码:
names = [" 张三 ", "", " 李四", "王五 ", " "]
result = [name.strip() for name in names if name.strip()]
print(result)
输出:
['张三', '李四', '王五']
解释:
name.strip() 去掉空格。
if name.strip() 过滤空字符串。
14.2 给成绩分类
scores = [95, 82, 60, 45, 78]
result = ["优秀" if score >= 90 else "合格" if score >= 60 else "不合格" for score in scores]
print(result)
输出:
['优秀', '合格', '合格', '不合格', '合格']
这段代码可以运行。
不过如果分类更多,建议用普通循环或函数来提高可读性。
14.3 生成学生成绩字典
names = ["张三", "李四", "王五"]
scores = [90, 85, 78]
score_dict = {name: score for name, score in zip(names, scores)}
print(score_dict)
输出:
{'张三': 90, '李四': 85, '王五': 78}
14.4 筛选及格学生
scores = {"张三": 90, "李四": 58, "王五": 76, "赵六": 45}
passed = {name: score for name, score in scores.items() if score >= 60}
print(passed)
输出:
{'张三': 90, '王五': 76}
14.5 提取不重复标签
tags = ["Python", "python", "Java", "java", "PYTHON"]
result = {tag.lower() for tag in tags}
print(result)
输出:
{'python', 'java'}
14.6 统计每个单词的长度
words = ["python", "java", "c"]
result = {word: len(word) for word in words}
print(result)
输出:
{'python': 6, 'java': 4, 'c': 1}
14.7 提取二维列表中的偶数
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
evens = [num for row in matrix for num in row if num % 2 == 0]
print(evens)
输出:
[2, 4, 6, 8]
14.8 统计不同字符
text = "hello python"
chars = {ch for ch in text if ch != " "}
print(chars)
print(len(chars))
输出可能是:
{'e', 'h', 'l', 'o', 'p', 'y', 't', 'n'}
8
15. 常见错误汇总
15.1 把字典推导式写成集合推导式
错误理解:
result = {x * x for x in range(5)}
这不是字典,而是集合。
如果想生成字典,要写成:
result = {x: x * x for x in range(5)}
15.2 忘记字典推导式中的冒号
错误写法:
result = {x, x * x for x in range(5)}
正确写法:
result = {x: x * x for x in range(5)}
字典推导式必须有 key: value。
15.3 单纯想打印时使用推导式
不推荐:
[print(x) for x in range(3)]
推荐:
for x in range(3):
print(x)
15.4 if...else 位置写错
错误写法:
result = [x for x in range(5) if x % 2 == 0 else 0]
正确写法:
result = [x if x % 2 == 0 else 0 for x in range(5)]
15.5 以为集合推导式会保留顺序
result = {x for x in [3, 1, 2]}
print(result)
集合不保证按列表原来的顺序输出。
如果需要顺序,用列表推导式。
15.6 以为圆括号是元组推导式
result = (x for x in range(5))
这不是元组,而是生成器。
如果要元组:
result = tuple(x for x in range(5))
15.7 字典键重复导致数据被覆盖
words = ["apple", "ant"]
result = {word[0]: word for word in words}
print(result)
输出:
{'a': 'ant'}
apple 被覆盖了。
如果希望一个键对应多个值,可以使用普通循环配合列表。
words = ["apple", "ant", "banana", "book"]
result = {}
for word in words:
first = word[0]
if first not in result:
result[first] = []
result[first].append(word)
print(result)
输出:
{'a': ['apple', 'ant'], 'b': ['banana', 'book']}
16. 课堂练习
练习 1:生成平方列表
请使用列表推导式生成 1 到 10 的平方列表。
参考答案:
result = [x * x for x in range(1, 11)]
print(result)
练习 2:筛选偶数
有如下列表:
nums = [1, 2, 3, 4, 5, 6, 7, 8]
请使用列表推导式筛选出所有偶数。
参考答案:
nums = [1, 2, 3, 4, 5, 6, 7, 8]
evens = [x for x in nums if x % 2 == 0]
print(evens)
练习 3:字符串转大写
有如下列表:
words = ["python", "java", "c++"]
请使用列表推导式把所有字符串转换成大写。
参考答案:
words = ["python", "java", "c++"]
result = [word.upper() for word in words]
print(result)
练习 4:生成数字平方字典
请使用字典推导式生成 1 到 5 的数字和平方对应关系。
参考答案:
result = {x: x * x for x in range(1, 6)}
print(result)
练习 5:筛选及格学生
有如下字典:
scores = {"张三": 90, "李四": 58, "王五": 76}
请使用字典推导式筛选出成绩大于等于 60 的学生。
参考答案:
scores = {"张三": 90, "李四": 58, "王五": 76}
passed = {name: score for name, score in scores.items() if score >= 60}
print(passed)
练习 6:创建姓名和编号字典
有如下列表:
names = ["张三", "李四", "王五"]
请生成这样的字典:
{1: "张三", 2: "李四", 3: "王五"}
参考答案:
names = ["张三", "李四", "王五"]
result = {index: name for index, name in enumerate(names, start=1)}
print(result)
练习 7:集合去重
有如下列表:
nums = [1, 2, 2, 3, 3, 3, 4]
请使用集合推导式去重。
参考答案:
nums = [1, 2, 2, 3, 3, 3, 4]
result = {x for x in nums}
print(result)
练习 8:提取不同字符
有如下字符串:
text = "hello"
请使用集合推导式提取其中不同的字符。
参考答案:
text = "hello"
chars = {ch for ch in text}
print(chars)
练习 9:二维列表展平
有如下二维列表:
matrix = [[1, 2], [3, 4], [5, 6]]
请使用列表推导式把它变成:
[1, 2, 3, 4, 5, 6]
参考答案:
matrix = [[1, 2], [3, 4], [5, 6]]
result = [num for row in matrix for num in row]
print(result)
练习 10:判断成绩是否通过
有如下成绩列表:
scores = [90, 58, 76, 45]
请使用列表推导式生成:
["通过", "不通过", "通过", "不通过"]
参考答案:
scores = [90, 58, 76, 45]
result = ["通过" if score >= 60 else "不通过" for score in scores]
print(result)
17. 教学总结
推导式是 Python 中非常实用的语法。
可以用一句话总结:
推导式就是用简洁的方式,从旧数据生成新数据。
三种常见推导式:
[表达式 for 变量 in 可迭代对象] # 列表推导式
{键表达式: 值表达式 for 变量 in 可迭代对象} # 字典推导式
{表达式 for 变量 in 可迭代对象} # 集合推导式
带条件筛选:
[表达式 for 变量 in 可迭代对象 if 条件]
带 if...else 处理:
[值1 if 条件 else 值2 for 变量 in 可迭代对象]
课堂记忆口诀:
列表推导用中括号,
字典推导有冒号,
集合推导会去重,
复杂逻辑别硬凑。
最后记住一个原则:
推导式适合简单清晰的转换和筛选。
如果逻辑复杂,普通 for 循环更好读。
评论区