Python教程12:列表进阶与推导式高级
“熟能生巧,巧能生精。”
在第8课我们学习了列表推导式的基础,今天我们深入探讨列表推导式的高级技巧和列表的进阶操作,让你的代码更加Pythonic和高效。
1. 回顾:列表推导式基础
1# 基础语法
2squares = [x**2 for x in range(10)]
3
4# 带条件
5evens = [x for x in range(10) if x % 2 == 0]
6
7# if-else
8result = [x if x > 0 else 0 for x in [-1, 2, -3, 4]]
2. 嵌套列表推导式
二维列表展平
1# 传统方法
2matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
3flat = []
4for row in matrix:
5 for num in row:
6 flat.append(num)
7
8# 列表推导式
9flat = [num for row in matrix for num in row]
10print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
理解技巧:从左到右阅读,就像嵌套的for循环。
创建二维列表
1# 创建3×3矩阵
2matrix = [[0 for _ in range(3)] for _ in range(3)]
3print(matrix)
4# [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
5
6# 创建乘法表
7table = [[i*j for j in range(1, 10)] for i in range(1, 10)]
8
9# 注意:不要这样创建二维列表
10# bad = [[0] * 3] * 3 # 错误!所有行是同一个对象
多重嵌套with条件
1# 找出两个列表的所有组合(有条件)
2a = [1, 2, 3]
3b = [3, 4, 5]
4
5# 找出和大于5的组合
6result = [(x, y) for x in a for y in b if x + y > 5]
7print(result) # [(2, 4), (2, 5), (3, 3), (3, 4), (3, 5)]
3. 列表推导式vs传统循环
1# 性能对比示例
2import time
3
4# 方法1:传统for循环
5start = time.time()
6result1 = []
7for i in range(100000):
8 result1.append(i**2)
9time1 = time.time() - start
10
11# 方法2:列表推导式
12start = time.time()
13result2 = [i**2 for i in range(100000)]
14time2 = time.time() - start
15
16print(f"传统循环:{time1:.4f}秒")
17print(f"列表推导式:{time2:.4f}秒")
18# 列表推导式通常快20-30%
4. 字典和集合推导式进阶
字典推导式高级用法
1# 统计字符出现次数
2text = "hello world"
3char_count = {char: text.count(char) for char in set(text) if char != ' '}
4
5# 从列表创建索引字典
6fruits = ['apple', 'banana', 'cherry']
7fruit_index = {fruit: i for i, fruit in enumerate(fruits)}
8
9# 嵌套字典推导式
10students = ['Alice', 'Bob']
11subjects = ['Math', 'English']
12grades = {
13 student: {subject: 0 for subject in subjects}
14 for student in students
15}
集合推导式妙用
1# 去重并转换
2numbers = [1, -2, 3, -4, 5]
3abs_unique = {abs(n) for n in numbers} # {1, 2, 3, 4, 5}
4
5# 找差异
6list1 = [1, 2, 3, 4, 5]
7list2 = [4, 5, 6, 7, 8]
8diff = {x for x in list1 if x not in list2} # {1, 2, 3}
5. 生成器表达式深入
1# 列表推导式:立即生成,占内存
2squares_list = [x**2 for x in range(1000000)]
3
4# 生成器表达式:按需生成,省内存
5squares_gen = (x**2 for x in range(1000000))
6
7# 使用生成器
8total = sum(x**2 for x in range(1000000))
9
10# 生成器只能遍历一次
11gen = (x for x in range(5))
12print(list(gen)) # [0, 1, 2, 3, 4]
13print(list(gen)) # [](已耗尽)
6. 列表的高级操作
zip和enumerate进阶
1# zip并行遍历
2names = ['Alice', 'Bob', 'Charlie']
3ages = [25, 30, 35]
4cities = ['Beijing', 'Shanghai', 'Guangzhou']
5
6# 创建字典
7people = [
8 {'name': n, 'age': a, 'city': c}
9 for n, a, c in zip(names, ages, cities)
10]
11
12# enumerate with start
13for i, name in enumerate(names, start=1):
14 print(f"{i}. {name}")
filter和map结合推导式
1# 虽然有filter和map,但推导式更清晰
2numbers = range(1, 11)
3
4# filter + map方式
5result1 = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, numbers)))
6
7# 推导式方式(更清晰)
8result2 = [x**2 for x in numbers if x % 2 == 0]
7. 实战案例
案例1:矩阵转置
1matrix = [
2 [1, 2, 3],
3 [4, 5, 6],
4 [7, 8, 9]
5]
6
7# 转置
8transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))]
9print(transposed)
10# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
11
12# 或使用zip
13transposed = [list(col) for col in zip(*matrix)]
案例2:笛卡尔积
1colors = ['红', '黑']
2sizes = ['S', 'M', 'L']
3products = [f"{color}-{size}" for color in colors for size in sizes]
4# ['红-S', '红-M', '红-L', '黑-S', '黑-M', '黑-L']
案例3:数据清洗
1# 清洗CSV数据
2raw_data = [
3 " Alice, 25 ",
4 "Bob,30",
5 " Charlie, 35 "
6]
7
8cleaned = [
9 [item.strip() for item in row.split(',')]
10 for row in raw_data
11]
8. 何时不用推导式
虽然推导式简洁,但有时不适合:
1# 太复杂(不推荐)
2result = [
3 [i*j for j in range(10) if j % 2 == 0]
4 for i in range(10)
5 if i % 3 == 0 and sum([i*j for j in range(10)]) > 20
6]
7
8# 应该用传统循环
9result = []
10for i in range(10):
11 if i % 3 == 0:
12 row = []
13 for j in range(10):
14 if j % 2 == 0:
15 row.append(i*j)
16 if sum(row) > 20:
17 result.append(row)
原则:超过两层嵌套或逻辑复杂时,用传统循环。
9. 小结
今天我们深入学习了列表推导式的高级技巧:
- 嵌套推导式:处理多维数据
- 性能优势:比传统循环快20-30%
- 字典/集合推导式:更多数据结构支持
- 生成器表达式:节省内存
- 高级操作:zip、enumerate、filter、map
- 实战案例:矩阵转置、笛卡尔积、数据清洗
- 使用原则:清晰胜于简洁
列表推导式是Python的精髓,掌握它能让代码更Pythonic!
练习题:
- 用列表推导式生成所有两位数的质数
- 创建一个单位矩阵(对角线为1,其他为0)
- 实现99乘法表(嵌套列表推导式)
本文代码示例: