Python 生成器实战:用 yield 搭建省内存的数据处理流水线

举报
yd_70403235 发表于 2026/11/15 09:17:53 2026/11/15
【摘要】 用生成器把“读一行、处理一行”串成流水线,处理大文件时不用一次性装进内存;附本地实测代码与验证结果。

Python 生成器实战:用 yield 搭建省内存的数据处理流水线

背景

日常开发里经常要处理比内存大得多的数据文件,比如几十万行的日志或订单导出表。最直观的写法是一次性把全部内容读进列表再处理,数据量一大就容易内存吃紧。Python 的生成器可以把“读一行、处理一行”变成一条流水线,数据流过即走,不必一次性装进内存。

实现思路

把处理过程拆成三个小步骤,每个步骤都是一个生成器:先逐行读取并转成数字,再过滤出偶数,最后把偶数翻倍。三个步骤用生成器表达式串起来,真正需要结果时才开始流动;求和时同样不需要先攒出完整列表。

代码示例

def read_numbers(path):
    """逐行读取文件,把非空行转成整数后逐个产出。"""
    with open(path, encoding="utf-8") as f:
        for line in f:
            line = line.strip()
            if line:
                yield int(line)


def pipeline(path):
    """读数、过滤偶数、翻倍,三段生成器串成一条流水线。"""
    numbers = read_numbers(path)
    evens = (n for n in numbers if n % 2 == 0)
    doubled = (n * 2 for n in evens)
    return doubled


if __name__ == "__main__":
    with open("demo_numbers.txt", "w", encoding="utf-8") as f:
        f.write("\n".join(str(i) for i in range(1, 11)))
    print(list(pipeline("demo_numbers.txt")))
    print(sum(pipeline("demo_numbers.txt")))

验证结果

本地 Python 3.12 实测:1 到 10 的偶数是 2、4、6、8、10,翻倍后得到 [4, 8, 12, 16, 20],求和为 60,与手工计算一致。需要注意 pipeline 返回的是生成器,只能消费一次;上面两次调用各建了一条新流水线,如果对同一条流水线先 list 再 sum,第二次会得到 0。

注意事项

生成器适合“读一点、处理一点、丢一点”的流式场景;如果后续步骤需要随机访问或反复遍历同一份数据,还是先转成列表更合适。文件句柄由 read_numbers 里的 with 管理,流水线消费完毕或中途丢弃时会自动关闭;中途用 break 退出循环时,生成器的 close 同样会触发清理。写流水线时尽量让每一步只做一件事,这样每一步都可以单独测试,也方便以后在中间再插入一步过滤或转换。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。