1. 什么是列表推导式?

列表推导式(List Comprehension)是 Python 中一种简洁、优雅的语法特性,用于快速创建列表。它允许我们在一行代码中完成对序列的迭代、过滤和转换操作,相比传统的 for 循环,代码更加简洁易读。

2. 基本语法

列表推导式的基本语法如下:

1
[表达式 for 变量 in 可迭代对象 if 条件]
  • 表达式:对每个元素执行的操作,结果将作为新列表的元素
  • 变量:从可迭代对象中取出的每个元素
  • 可迭代对象:可以是列表、元组、字符串、range 等
  • 条件(可选):过滤条件,只有满足条件的元素才会被处理

3. 基础用法

3.1 简单列表生成

1
2
3
4
5
6
7
8
9
10
11
12
# 生成 0-9 的平方列表
squares = [x ** 2 for x in range(10)]
print(squares) # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 生成 1-10 的偶数列表
evens = [x for x in range(1, 11) if x % 2 == 0]
print(evens) # 输出: [2, 4, 6, 8, 10]

# 将字符串转换为字符列表
word = "Python"
characters = [c for c in word]
print(characters) # 输出: ['P', 'y', 't', 'h', 'o', 'n']

3.2 嵌套循环

列表推导式支持嵌套循环,用于处理多维数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 生成二维列表(九九乘法表)
times_table = [[i * j for j in range(1, 10)] for i in range(1, 10)]
print(times_table)
# 输出:
# [[1, 2, 3, 4, 5, 6, 7, 8, 9],
# [2, 4, 6, 8, 10, 12, 14, 16, 18],
# ...
# [9, 18, 27, 36, 45, 54, 63, 72, 81]]

# 扁平化二维列表
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(flattened) # 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]

3.3 条件过滤

可以在列表推导式中添加条件,过滤不需要的元素:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 过滤出大于 5 的数字
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
greater_than_five = [x for x in numbers if x > 5]
print(greater_than_five) # 输出: [6, 7, 8, 9, 10]

# 过滤出元音字母
word = "Hello World"
vowels = [c for c in word if c.lower() in 'aeiou']
print(vowels) # 输出: ['e', 'o', 'o']

# 组合多个条件
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
filtered = [x for x in numbers if x % 2 == 0 and x > 5]
print(filtered) # 输出: [6, 8, 10]

4. 高级应用

4.1 与函数结合

列表推导式可以与内置函数或自定义函数结合使用:

1
2
3
4
5
6
7
8
9
10
11
# 使用内置函数
numbers = [-1, 2, -3, 4, -5]
absolute_values = [abs(x) for x in numbers]
print(absolute_values) # 输出: [1, 2, 3, 4, 5]

# 使用自定义函数
def square(x):
return x ** 2

squares = [square(x) for x in range(5)]
print(squares) # 输出: [0, 1, 4, 9, 16]

4.2 字典和集合推导式

Python 还支持字典推导式和集合推导式:

1
2
3
4
5
6
7
8
9
# 字典推导式:创建字典
numbers = [1, 2, 3, 4, 5]
square_dict = {x: x ** 2 for x in numbers}
print(square_dict) # 输出: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# 集合推导式:创建集合(自动去重)
words = ["apple", "banana", "apple", "orange", "banana"]
unique_words = {word for word in words}
print(unique_words) # 输出: {'apple', 'banana', 'orange'}

4.3 生成器表达式

生成器表达式与列表推导式类似,但使用圆括号而不是方括号,返回的是一个生成器对象,更加节省内存:

1
2
3
4
5
6
7
8
9
10
# 生成器表达式
squares = (x ** 2 for x in range(10))
print(squares) # 输出: <generator object <genexpr> at 0x...>

# 转换为列表
print(list(squares)) # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 直接迭代
for square in (x ** 2 for x in range(5)):
print(square) # 输出: 0, 1, 4, 9, 16

5. 实际应用案例

5.1 数据转换

1
2
3
4
5
6
7
8
9
# 将字符串列表转换为整数列表
str_numbers = ["1", "2", "3", "4", "5"]
int_numbers = [int(x) for x in str_numbers]
print(int_numbers) # 输出: [1, 2, 3, 4, 5]

# 将列表中的元素转换为大写
words = ["hello", "world", "python"]
upper_words = [word.upper() for word in words]
print(upper_words) # 输出: ['HELLO', 'WORLD', 'PYTHON']

5.2 数据过滤

1
2
3
4
5
6
7
8
9
# 过滤出长度大于 3 的字符串
words = ["a", "ab", "abc", "abcd", "abcde"]
long_words = [word for word in words if len(word) > 3]
print(long_words) # 输出: ['abcd', 'abcde']

# 过滤出包含特定字符的字符串
words = ["apple", "banana", "cherry", "date"]
contains_a = [word for word in words if 'a' in word]
print(contains_a) # 输出: ['apple', 'banana', 'date']

5.3 组合数据

1
2
3
4
5
6
7
8
9
10
11
# 组合两个列表的元素
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
combined = [(x, y) for x in list1 for y in list2]
print(combined) # 输出: [(1, 'a'), (1, 'b'), (1, 'c'), (2, 'a'), (2, 'b'), (2, 'c'), (3, 'a'), (3, 'b'), (3, 'c')]

# 笛卡尔积
colors = ["red", "green", "blue"]
sizes = ["S", "M", "L"]
combinations = [(color, size) for color in colors for size in sizes]
print(combinations) # 输出: [('red', 'S'), ('red', 'M'), ('red', 'L'), ('green', 'S'), ...]

5.4 矩阵操作

1
2
3
4
5
6
7
8
9
# 转置矩阵
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
transposed = [[row[i] for row in matrix] for i in range(len(matrix[0]))]
print(transposed) # 输出: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

# 矩阵元素平方
matrix = [[1, 2], [3, 4]]
squared = [[x ** 2 for x in row] for row in matrix]
print(squared) # 输出: [[1, 4], [9, 16]]

6. 性能对比

列表推导式相比传统的 for 循环,不仅代码更简洁,而且执行速度通常更快:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import time

# 使用传统 for 循环
start = time.time()
squares = []
for i in range(1000000):
squares.append(i ** 2)
end = time.time()
print(f"传统 for 循环耗时: {end - start:.6f} 秒")

# 使用列表推导式
start = time.time()
squares = [i ** 2 for i in range(1000000)]
end = time.time()
print(f"列表推导式耗时: {end - start:.6f} 秒")

7. 注意事项与最佳实践

7.1 注意事项

  • 可读性:不要在列表推导式中放入过于复杂的逻辑,以免降低代码可读性
  • 内存消耗:对于大型数据集,列表推导式会一次性创建整个列表,可能消耗较多内存。此时可以考虑使用生成器表达式
  • 嵌套深度:嵌套循环的列表推导式可能会变得难以理解,建议嵌套层数不超过 2 层

7.2 最佳实践

  • 保持简洁:只在逻辑简单时使用列表推导式
  • 合理使用:对于复杂的逻辑,建议使用传统的 for 循环,提高代码可读性
  • 结合条件:充分利用条件过滤,减少后续的处理步骤
  • 性能考虑:对于大数据集,优先考虑生成器表达式

8. 与其他语言的对比

8.1 Python vs JavaScript

1
2
3
4
5
# Python 列表推导式
squares = [x ** 2 for x in range(10)]

# JavaScript 箭头函数 + map
squares = Array.from({length: 10}, (_, i) => i ** 2);

8.2 Python vs Java

1
2
3
4
5
6
7
8
# Python 列表推导式
evens = [x for x in range(1, 11) if x % 2 == 0]

# Java 流操作
List<Integer> evens = IntStream.range(1, 11)
.filter(x -> x % 2 == 0)
.boxed()
.collect(Collectors.toList());