← [ BACK_TO_NOTES ]

Python 推导式与生成器表达式

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

#concept #growing #dev #python #python

[!info] related notes

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: 2

(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
  • Python 3 的推导式循环目标不会泄漏到外围作用域;这不表示其中所有赋值都局部化,:= 通常绑定到包含它的作用域,并有使用限制。
  • 可嵌套 for,但要克制

边界情况与反直觉行为

  1. 生成器耗尽后为空,不能当列表反复遍历除非物化。
  2. 字典推导式产生重复键时保留最后的值;集合推导去重且无插入顺序保证,不应将两者当作无损列表转换。
  3. 生成器表达式最左侧 for 的 iterable 表达式和迭代器创建立即发生;其余取值、过滤和元素表达式通常等消费时才执行,因此异常既可能在构造时也可能在迭代时出现。

常见误区

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

工程实践

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

本节总结

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

自测题

  1. 列表推导与生成器表达式在内存上的关键差别?
  2. 何时不该用推导?
参考答案
  1. 列表立即物化全部元素;生成器按需产出但会保留迭代状态和引用,输入已物化或后续再 list(…) 时仍可能占用大量内存。
  2. 需要多语句、复杂分支或明显副作用时。

延伸阅读与资料来源

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

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本