Python 推导式与生成器表达式

列表/集合/字典推导与生成器表达式用声明式构造数据;注意作用域、可读性与惰性求值边界。

#type / concept #status / growing #tech / dev #resource / python #tech / lang / python

[!info] 关联笔记

Python 推导式与生成器表达式

这个概念为什么出现

从一批订单过滤出待发货 ID、从日志抽状态码——用 for + append 冗长。推导式把“映射/过滤”压缩为表达式;生成器表达式则惰性产出,避免一次性物化大列表。

[!abstract] 一句话理解 推导式声明式构建 list/set/dict;生成器表达式用圆括号惰性产出元素,可迭代一次。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:订单中心筛选可发货单并统计渠道

# orders_comprehension.py
# 业务意图:过滤 paid 订单、映射发货任务、统计渠道集合。
# 教学点:
# - list/set/dict 推导;
# - 生成器表达式节省中间列表;
# - 可读性:复杂逻辑不要硬塞一行。

def main() -> None:
    orders = [
        {"id": "O1", "status": "paid", "channel": "app"},
        {"id": "O2", "status": "cancel", "channel": "web"},
        {"id": "O3", "status": "paid", "channel": "app"},
    ]

    ship_ids = [o["id"] for o in orders if o["status"] == "paid"]
    channels = {o["channel"] for o in orders}
    status_index = {o["id"]: o["status"] for o in orders}

    total_paid = sum(1 for o in orders if o["status"] == "paid")  # 生成器表达式

    print("ship:", ship_ids)
    print("channels:", channels)
    print("index:", status_index)
    print("paid count:", total_paid)


if __name__ == "__main__":
    main()

建议运行:

python orders_comprehension.py

期望输出:

ship: ['O1', 'O3']
channels: {'app', 'web'}
index: {'O1': 'paid', 'O2': 'cancel', 'O3': 'paid'}
paid count: 3

channels 集合展示顺序可能不同。)

结合场景再看三个关注点

  1. 过滤 + 映射是推导式主场。
  2. sum(1 for ...) 不必先建 list。
  3. 嵌套三层推导通常应拆函数。

核心概念与准确模型

[expr for x in xs if cond]
{expr for x in xs}
{k: v for x in xs}
(expr for x in xs)  # generator
  • 推导式有独立作用域(3.x 列表推导循环变量不泄漏)
  • 可嵌套 for,但要克制

边界情况与反直觉行为

  1. 生成器耗尽后为空,不能当列表反复遍历除非物化。
  2. 海象 := 可在推导中赋值,但易损害可读性。
  3. 异常在迭代时才抛出(生成器)。

常见误区

[!warning] 常见误区:所有循环都改成推导 错误理解:推导一定更 Pythonic。
正确模型:有副作用(写库、打印)的流程用 for;纯映射过滤用推导。

工程实践

  • 超过两层条件拆函数命名。
  • 大数据管线优先生成器/迭代器链。
  • map/filter 二选一,团队统一风格。

本节总结

推导式提升表达密度;生成器表达式控制内存。可读性永远优先于“一行装下宇宙”。

自测题

  1. 列表推导与生成器表达式在内存上的关键差别?
  2. 何时不该用推导?
参考答案
  1. 列表立即物化全部元素;生成器按需产出。
  2. 需要多语句、复杂分支或明显副作用时。

延伸阅读与资料来源

资料类型支撑内容
Data Structures – List Comprehensions教程推导式
Generator expressions规范语法
创建于 2026/7/15 更新于 2026/7/15