当前位置:首页>python>Python列表推导式:用法·技巧·案例

Python列表推导式:用法·技巧·案例

  • 2026-10-11 06:24:36
Python列表推导式:用法·技巧·案例

一、列表推导式基础

列表推导式(list comprehension)是 Python 中一种简洁、高效地创建列表的方式。它可以把多行循环 + 条件判断压缩成一行表达式,同时保持可读性。

列表创建有三种方式:字面量方式、构造器方式、推导式方式。本次主要探讨列表的推导式方式。

基本语法

[表达式 for 变量 in 可迭代对象]
  • 表达式:对每个元素进行的操作(可以是计算、函数调用、字符串格式化等)
  • 变量:从可迭代对象中取出的每个元素
  • 可迭代对象:列表、元组、range、字符串、字典等

示例1:生成平方数列表

# 普通写法
squares = []
for i in range(1, 6):
    squares.append(i ** 2)
print(squares)
# 输出: [1, 4, 9, 16, 25]

# 列表推导式
squares = [i ** 2for i in range(1, 6)]
print(squares)
# 输出: [1, 4, 9, 16, 25]

二、添加条件筛选

在推导式末尾加上 if 条件,只保留满足条件的元素。

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

示例2:过滤偶数

even_nums = [x for x in range(10) if x % 2 == 0]
print(even_nums)
# 输出:[0, 2, 4, 6, 8]

三、嵌套循环

两个(或多个)for 子句,相当于扁平化的嵌套循环。

[表达式 for 变量1in 可迭代1for 变量2in 可迭代2]

示例3:二维坐标扁平化

coord_datas = [(x, y) for x in range(2) for y in range(3)]
print(coord_datas)
# 输出: [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2)]

四、带有 if-else 的表达式

注意区分:if 放在 表达式内部 用于三元条件运算,放在 末尾 用于过滤。

# 三元条件:根据条件选择不同的表达式
[表达式A if 条件 else 表达式B for 变量 in 可迭代对象]

示例4:将奇数变为字符串"odd",偶数变为"Even"

result = [x for x in range(5)]
print(result)  # [0, 1, 2, 3, 4]
result = ['Even'if x % 2 == 0else"odd"for x in range(5)]
print(result)
# 输出:['Even', 'odd', 'Even', 'odd', 'Even']

五、高级技巧

1. 使用函数作为表达式

import math
roots = [math.sqrt(x) for x in range(1, 6)]
print([round(r, 2) for r in roots])
# 输出: [1.0, 1.41, 1.73, 2.0, 2.24]

2. 多变量同时迭代

利用 zip 打包多个列表。

names = ["小红", "小黄", "小蓝"]
scores = [95, 87, 92]
info = [f"{name}: {score}"for name, score in zip(names, scores)]
print(info) 
# 输出:['小红: 95', '小黄: 87', '小蓝: 92']

3. 从嵌套列表提取元素

# 矩阵
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 扁平化转换
flatten = [num for row in matrix for num in row]
print(flatten)
# 输出:[1,2,3,4,5,6,7,8,9]

六、性能提示

  • 列表推导式通常比等效的 for 循环更快,因为它在底层使用 C 级别的执行。
  • 但如果嵌套过多或逻辑复杂,可读性会下降,此时应拆分为普通循环。

七、趣味例子

1. 使用 random 模拟掷骰子

import random

# 生成 20 个 1~6 的随机数,只保留大于 4 的点数
high_rolls = [roll for roll in (random.randint(1, 6) for _ in range(20)) if roll > 4]
print(high_rolls)  
# 输出: [5, 6, 5, 6, 6, 5]

2. 使用 math 生成勾股数

import math
# 限制 a, b 在 1~20 之间,c 为整数
triples = [(a, b, c) for a in range(1, 21) for b in range(a, 21) 
for c in range(b, 21) if a**2 + b**2 == c**2]
print(triples[:5])
# 输出: [(3,4,5), (5,12,13), (6,8,10), (7,24,25), (8,15,17)]

3. 使用 itertools 生成笛卡尔积并格式化

import itertools

colors = ['红', '绿', '蓝']
sizes = ['R', 'G', 'B']
products = [f"{color}{size}"for color, size in itertools.product(colors, sizes)]
print(products)
# 输出:['红R', '红G', '红B', '绿R', '绿G', '绿B', '蓝R', '蓝G', '蓝B']

4. 使用 datetime 生成过去 7 天的日期

from datetime import datetime, timedelta

today = datetime.now()
last_7_days = [(today - timedelta(days=i)).strftime('%Y-%m-%d') for i in range(7)]
print(last_7_days)
# 输出:['2026-06-06', '2026-06-05', '2026-06-04', '2026-06-03', '2026-06-02', '2026-06-01', '2026-05-31']

5. 使用 pathlib 获取当前目录下所有 .py 文件

from pathlib import Path

py_files = [f.name for f in Path('.').iterdir() if f.suffix == '.py']
print(py_files)  # ['demo.py', 'utils.py', ...]

6. 使用 string + random 生成随机密码(8 位字母数字)

import string, random

chars = string.ascii_letters + string.digits
passwords = [''.join(random.choices(chars, k=8)) for _ in range(5)]
print(passwords)  # ['aB3dE9kL', 'xY7zQ2pR', ...]

7. 使用 statistics 计算多组数据的方差(模拟)

import statistics

data_sets = [[1,2,3], [4,5,6], [7,8,9]]
var_results = [statistics.variance(data) for data in data_sets]
print(var_results)  # [1.0, 1.0, 1.0]

8. 模拟从 API 响应中提取字段(使用 json)

import json

api_response = '''
[
    {"name": "Alice", "age": 25},
    {"name": "Bob", "age": 30},
    {"name": "Cathy", "age": 28}
]
'''

data = json.loads(api_response)
names = [person['name'] for person in data]
print(names)  # ['Alice', 'Bob', 'Cathy']

9. 生成斐波那契数列的部分元素(演示推导式)

# 直接使用列表推导式无法递归,但可以用赋值技巧
fib = [0, 1]
[fib.append(fib[-1] + fib[-2]) for _ in range(8)]  # 副作用,不推荐
print(fib)
# 输出:[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

更推荐的做法:普通循环。这里仅展示列表推导式的“副作用”用法(实际不推荐)。

10. 使用 math 和列表推导式实现素数筛的变种(埃氏筛思想)

import math

defis_prime(n):
if n < 2: returnFalse
return all(n % i != 0for i in range(2, int(math.sqrt(n)) + 1))

primes = [x for x in range(2, 50) if is_prime(x)]
print(primes)  # [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47]

八、总结

场景
推荐使用推导式
避免使用推导式
简单转换或过滤
✅
❌
嵌套循环(≤2层)
✅
⚠️ 超过2层可读性差
需要异常处理
❌
✅ 用普通循环+try
状态累积(如斐波那契)
❌
✅ 用循环
大量逻辑判断
❌
✅ 拆解为函数+推导式

掌握列表推导式可以让你的 Python 代码更加简洁优雅,但请始终记住 “可读性优先”。如果一行写不下,就拆成几行或改用普通循环。

练习建议:尝试用列表推导式改写你最近写过的 for 循环,体会简洁与性能的提升。

最新文章

随机文章