01-Python学习之列表
Python 3 列表推导式(List Comprehension)
列表推导式是 Python 中一种简洁而强大的语法,用于从已有的可迭代对象创建新列表。它可以用一行代码完成原本需要多行循环和条件判断才能完成的工作。
一、基本语法
[表达式 for 变量 in 可迭代对象]
最简单的例子——生成 0 到 9 的平方列表:
squares = [x ** 2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
对比传统的写法,你会立刻感受到它的简洁:
# 传统写法
squares = []
for x in range(10):
squares.append(x ** 2)
两种写法结果完全一样,但列表推导式更紧凑、更 Pythonic。
二、带条件过滤
在 for 循环后面加上 if 条件,可以筛选元素:
[表达式 for 变量 in 可迭代对象 if 条件]
示例: 从一个列表中筛选出所有偶数
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = [x for x in numbers if x % 2 == 0]
# [2, 4, 6, 8, 10]
示例: 从字符串列表中筛选长度大于 3 的单词
words = ["hi", "hello", "hey", "world", "ok"]
long_words = [w for w in words if len(w) > 3]
# ['hello', 'world']
三、带 if-else 的表达式
注意,这与"条件过滤"不同。这里的 if-else 放在表达式的位置,用来决定输出的值:
[表达式1 if 条件 else 表达式2 for 变量 in 可迭代对象]
示例: 将列表中的正数保留,负数变为 0
numbers = [3, -1, 4, -2, 0, 5]
result = [x if x > 0 else 0 for x in numbers]
# [3, 0, 4, 0, 0, 5]
易混淆点:
if放在for后面是"过滤"(决定要不要这个元素),if-else放在for前面是"变换"(决定这个元素变成什么)。两者可以结合使用。
四、嵌套循环
列表推导式支持多层 for 循环,从左到右对应从外层到内层:
[表达式 for 变量1 in 可迭代对象1 for 变量2 in 可迭代对象2]
示例: 生成所有两位数的坐标对
pairs = [(x, y) for x in range(3) for y in range(3)]
# [(0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2)]
示例: 展平一个二维列表
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
五、实际应用示例
1. 文件名批量处理
files = ["report.pdf", "data.csv", "image.png", "notes.txt"]
pdf_files = [f for f in files if f.endswith(".pdf")]
# ['report.pdf']
2. 字典键值对转换
prices = {"apple": 3.5, "banana": 2.0, "cherry": 5.0}
expensive = [fruit for fruit, price in prices.items() if price > 3.0]
# ['apple', 'cherry']
3. 字符串处理
sentence = "Hello World Python"
upper_words = [word.upper() for word in sentence.split()]
# ['HELLO', 'WORLD', 'PYTHON']
4. 数学运算
# 生成 30 以内所有能被 3 和 5 同时整除的数
result = [x for x in range(1, 31) if x % 3 == 0 and x % 5 == 0]
# [15, 30]
六、推导式的其他形式
列表推导式的思想同样适用于其他数据结构:
字典推导式
words = ["hello", "world", "python"]
word_lengths = {w: len(w) for w in words}
# {'hello': 5, 'world': 5, 'python': 6}
集合推导式
numbers = [1, 2, 2, 3, 3, 3, 4]
unique_squares = {x ** 2 for x in numbers}
# {1, 4, 9, 16}
生成器表达式
将方括号 [] 换成圆括号 (),就变成了生成器表达式——它不会一次性生成所有数据,而是按需产出,节省内存:
total = sum(x ** 2 for x in range(1000000)) # 不会占用大量内存
七、可读性建议
列表推导式虽然强大,但不应该滥用。核心原则:
- 一行能看懂的,用推导式。 如果逻辑复杂到需要反复琢磨,就用普通
for循环。 - 嵌套不要超过两层。 超过两层时,代码的可读性会急剧下降。
- 推导式适合创建列表,不适合执行副作用。 如果目的只是遍历去做某些操作(比如打印、修改外部变量),请用普通循环。
# 好的用法:创建数据
squares = [x ** 2 for x in range(10)]
# 不好的用法:执行副作用
[print(x) for x in range(10)] # 虽然能运行,但别这么做
八、速查表
| 语法 | 用途 |
|---|---|
[x for x in iterable] |
基本映射 |
[x for x in iterable if cond] |
条件过滤 |
[a if cond else b for x in iterable] |
条件变换 |
[x for a in A for x in a] |
嵌套循环(展平) |
{k: v for k, v in iterable} |
字典推导式 |
{x for x in iterable} |
集合推导式 |
(x for x in iterable) |
生成器表达式 |
本文来自博客园,作者:code0101,转载请注明原文链接:https://www.cnblogs.com/cmct/p/20042497
浙公网安备 33010602011771号