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. 用列表推导式生成所有两位数的质数
  2. 创建一个单位矩阵(对角线为1,其他为0)
  3. 实现99乘法表(嵌套列表推导式)

本文代码示例


相关阅读