当前位置:首页>python>Python:列表推导式

Python:列表推导式

  • 2026-09-09 15:18:44
Python:列表推导式

列表推导式(List Comprehension)是 Python 中用于生成列表的一种简洁语法,它可以把遍历、条件筛选、元素转换和结果收集写在一个表达式中,适合构造结构简单的新列表。

一、什么是列表推导式

1、基本语法

列表推导式使用方括号 [ ] 生成列表,基本形式为:

[输出表达式 for 变量 in 可迭代对象]

例如,生成 0 到 4 的平方:

squares = [x ** 2 for x in range(5)]print(squares)

输出:

[0, 1, 4, 9, 16]

这段列表推导式可以分成三个部分:

x ** 2          # 对当前元素进行计算for x           # 将当前元素依次绑定给 xin range(5)     # 指定要遍历的数据

列表推导式会依次遍历 range(5) 中的元素,对每个元素计算 x ** 2,再把结果收集到新列表中。

2、与普通循环的对应关系

列表推导式:

squares = [x ** 2 for x in range(5)]

等价于:

squares = []for x in range(5):    squares.append(x ** 2)

两种写法都完成了三个步骤:

• 遍历可迭代对象

• 处理当前元素

• 将结果加入新列表

在 Python 3 中,列表推导式中的循环变量只在推导式内部有效,不会覆盖外部的同名变量。

3、输出表达式决定列表元素

列表推导式中,for 前面的表达式决定新列表中要保存什么内容。

例如,将数字及其平方组成元组:

pairs = [(x, x ** 2) for x in range(5)]print(pairs)

输出:

[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16)]

虽然元素可以是数字、字符串、元组、列表、字典或其他对象,但列表推导式生成的结果始终是列表。

二、带条件的列表推导式

列表推导式中的条件主要有两种用途:

• 条件筛选:决定当前遍历到的元素是否参与结果生成

• 条件表达式:根据条件选择当前要生成的新列表元素

两种写法中,if 所在的位置不同。

1、条件筛选

在 for 后面添加 if,可以只保留满足条件的元素。

基本语法:

[输出表达式 for 变量 in 可迭代对象 if 条件]

这里的 if 用于过滤元素。只有条件成立时,当前元素才会送入输出表达式。

例如,筛选偶数并计算平方:

even_squares = [    x ** 2    for x in range(10)    if x % 2 == 0]print(even_squares)

输出:

[0, 4, 16, 36, 64]

等价写法为:

even_squares = []for x in range(10):    if x % 2 == 0:        even_squares.append(x ** 2)print(even_squares)

2、条件表达式

条件表达式可以看作输出表达式的一种形式,用于根据条件生成不同结果。

基本语法:

[结果1 if 条件 else 结果2 for 变量 in 可迭代对象]

例如,为数字添加奇偶标签:

labels = [    "even" if x % 2 == 0 else "odd"    for x in range(5)]print(labels)

输出:

['even', 'odd', 'even', 'odd', 'even']

等价写法为:

labels = []for x in range(5):    if x % 2 == 0:        labels.append("even")    else:        labels.append("odd")

三、与常用遍历工具组合

列表推导式经常与 range()、enumerate()、zip()等遍历工具,以及对象方法和自定义函数配合使用。

1、与 range() 配合

range() 常用于生成整数序列。

row_names = [    f"第{x}行"    for x in range(1, 5)]print(row_names)

输出:

['第1行', '第2行', '第3行', '第4行']

2、与 enumerate() 配合

enumerate() 可以在遍历元素时,同时得到元素的索引和值。

words = ["python", "java", "c++"]indexed_words = [    (index, word)    for index, word in enumerate(words)]print(indexed_words)

输出:

[(0, 'python'), (1, 'java'), (2, 'c++')]

如果希望编号从 1 开始,可以使用 start 参数:

enumerate(words, start=1)

3、与 zip() 配合

zip() 可以同时遍历多个可迭代对象中相同位置的元素。

names = ["张三", "李四", "王五"]scores = [90, 82, 95]records = [    f"{name}: {score}"    for name, score in zip(names, scores)]print(records)

输出:

['张三: 90', '李四: 82', '王五: 95']

需要注意,zip() 会在最短的可迭代对象结束时停止。

4、调用方法或自定义函数

列表推导式的输出表达式可以直接调用对象方法。

例如,去除字符串两端的空白并转换为小写:

words = ["  Python ", " Java", "C++  "]cleaned_words = [    word.strip().lower()    for word in words]print(cleaned_words)

输出:

['python', 'java', 'c++']

也可以调用自定义函数:

def double(value):    return value * 2numbers = [1, 2, 3, 4]results = [    double(number)    for number in numbers]print(results)

输出:

[2, 4, 6, 8]

当处理逻辑稍长时,可以先将逻辑封装为函数,再在列表推导式中调用。这样通常比直接堆叠复杂表达式更容易理解。

四、包含多个 for 子句的列表推导式

列表推导式中可以连续使用多个 for 子句,表示多层循环。

基本语法:

[输出表达式 for 变量1 in 可迭代对象1 for 变量2 in 可迭代对象2]

其中,for 子句从左到右对应普通循环由外到内的顺序。

例如,生成二维坐标点:

points = [    (x, y)    for x in range(2)    for y in range(3)]print(points)

输出:

[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2)]

等价写法为:

points = []for x in range(2):    for y in range(3):        points.append((x, y))

因此,在:

[(x, y) for x in range(2) for y in range(3)]

中:

• for x 是外层循环

• for y 是内层循环

多个 for 子句后面同样可以添加筛选条件。

例如,筛选出 x 与 y 之和为偶数的组合:

pairs = [    (x, y)    for x in range(3)    for y in range(3)    if (x + y) % 2 == 0]print(pairs)

输出:

[(0, 0), (0, 2), (1, 1), (2, 0), (2, 2)]

这相当于:

pairs = []for x in range(3):    for y in range(3):        if (x + y) % 2 == 0:            pairs.append((x, y))

多个 for 子句产生的结果同样会送入输出表达式,因此通常仍然会形成扁平列表。

五、嵌套列表推导式

嵌套列表推导式是指:一个列表推导式的输出表达式部分,本身又是另一个列表推导式。

基本形式为:

[

    [内层输出表达式 for 内层变量 in 内层可迭代对象]

    for 外层变量 in 外层可迭代对象

]

通常可用于生成二维列表或其他嵌套结构。

例如,生成 3 行、4 列的二维列表:

matrix = [    [0 for column in range(4)]    for row in range(3)]print(matrix)

输出:

[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

等价写法为:

matrix = []for row in range(3):    result_row = []    for column in range(4):        result_row.append(0)    matrix.append(result_row)print(matrix)

外层循环每执行一次,就会生成一个完整的内层列表。

再例如,使用嵌套列表推导式实现转置:

A = [    [1, 2, 3],    [4, 5, 6]]column_count = len(A[0])result = [    [        A[row][column]        for row in range(len(A))    ]    for column in range(column_count)]print(result)

输出:

[[1, 4], [2, 5], [3, 6]]

可以看出,嵌套列表推导式没有引入新的语法规则,本质上是将外层列表推导式的输出表达式写成另一个列表推导式。

六、其他推导式速览

除列表推导式外,Python 还支持集合推导式、字典推导式和生成器表达式。

1、集合推导式

集合推导式使用花括号 { } 生成集合:

values = {x % 3 for x in range(6)}

结果:

{0, 1, 2}

集合会自动去除重复元素。

2、字典推导式

字典推导式也使用花括号 { },并且需要在输出表达式中提供键值对:

mapping = {    x: x ** 2    for x in range(5)}

结果:

{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

3、生成器表达式

生成器表达式使用圆括号 ( ),不会一次性保存全部结果,而是在迭代时按需产生元素。处理大量数据时通常更节省内存。

例如:

generator = (x ** 2 for x in range(5))print(next(generator))print(next(generator))

输出:

01

七、常见问题及使用建议

1、优先保证可读性

列表推导式在简单场景中可能比普通循环更紧凑或更高效,但选择写法时应优先考虑可读性。

需要多个步骤、异常处理或中间变量时,普通循环通常更合适。

2、避免堆叠过多逻辑

下面的写法虽然能够运行,但较难阅读:

result = [    x * y    for x in range(5)    if x % 2 == 0    for y in range(5)    if y % 2 == 1]

当推导式中包含多个循环、多个条件或复杂表达式时,普通循环通常更加清楚。

3、避免副作用操作

列表推导式的主要目的,是根据已有数据生成新列表。

不建议只为了执行输出或修改外部状态而使用:

[print(x) for x in range(5)]

这段代码会生成一个由 None 组成的列表:

[None, None, None, None, None]

如果只是需要输出,应使用普通循环:

for x in range(5):    print(x)

如果主要目的是输出、写入文件或修改外部状态,应使用普通循环明确表达。

📘 小结

列表推导式可以在遍历过程中完成元素转换和条件筛选,适合生成结构简单的新列表。多个 for 子句通常将结果直接收集到同一个列表中,嵌套列表推导式则用于生成嵌套结构。使用时应优先保证代码清晰,避免堆叠过多逻辑和执行副作用操作。

“点赞有美意,赞赏是鼓励”

最新文章

随机文章