列表推导式(list comprehension)在 Python 中用于由可迭代对象一次性生成列表,基本形式为 [表达式 for 变量 in 可迭代对象],可在末尾加 if 过滤元素。本节对照普通 for 循环说明写法、条件过滤、三元表达式与嵌套循环,并讨论可读性与适用边界。

循环写法与推导式对照

生成 0 到 9 各数的平方,使用循环通常需要初始化空列表并多次 append:

squares = []
for i in range(10):
    squares.append(i * i)
print(squares)   # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

等价推导式可写为一行:

squares = [i * i for i in range(10)]
print(squares)   # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

阅读顺序为:先确定生成的表达式,再确认数据来源(for … in …)。

基础写法

# 对每个元素做变换
names = ["alice", "bob", "carol"]
upper_names = [n.upper() for n in names]
print(upper_names)   # ['ALICE', 'BOB', 'CAROL']

# 从字符串拆
chars = [c for c in "Python"]
print(chars)         # ['P', 'y', 't', 'h', 'o', 'n']

带条件:过滤

在 for 子句之后添加 if,仅保留满足条件的元素:

Python 列表推导式带条件过滤示例运行
nums = [1, 2, 3, 4, 5, 6]
evens = [n for n in nums if n % 2 == 0]
print(evens)   # [2, 4, 6]

words = ["hi", "", "world", "", "py"]
non_empty = [w for w in words if w]
print(non_empty)   # ['hi', 'world', 'py'],空串是假值被过滤

带 else 的条件表达式

若每个输入元素都需对应一个输出值,可将三元表达式写在 for 之前:

nums = [1, 2, 3, 4]
tags = ["even" if n % 2 == 0 else "odd" for n in nums]
print(tags)   # ['odd', 'even', 'odd', 'even']

嵌套循环

pairs = [(x, y) for x in range(3) for y in range(3)]
print(pairs)
# [(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(2,0),(2,1),(2,2)]

清洗数据示例

data = [" 12 ", "34", "  ", "56", "-1"]
clean = [int(x.strip()) for x in data if x.strip().isdigit()]
print(clean)   # [12, 34, 56]

此处先调用 strip 去除空白,再用 isdigit 排除非数字项,最后转为 int,过滤与转换写在同一条推导式中。

关于效率

推导式通常比手写 append 循环更紧凑,在数据量较大时往往也更快。若表达式过长或逻辑分支过多,应改回普通循环以保持可读性。

两道小练习

写一个推导式,生成 1 到 20 中能被 3 整除的数的平方列表。另写一个:将一句英文按单词拆分,并去掉长度小于 3 的项。

本节说明了 Python 列表推导式的语法与典型用法。下一篇介绍元组:有序而不可变的序列及解包规则。