1分钟解锁Python神技:用生成器轻松处理1亿条数据!

欢迎来到「每天1分钟,轻松懂Python」!今天的主角是:生成器。

它能让你用几乎忽略不计的内存,处理无限大的数据流。比如,轻松遍历1亿条数据而不会撑爆你的内存。

核心价值就一点:惰性计算------需要时才生产,绝不提前浪费空间。

1分钟时间,我们从概念、代码、案例出发。让你不仅看懂,更能马上用起来!

容器、可迭代对象、迭代器

容器:在 Python 中一切皆为对象,对象的集合就是容器。

可迭代对象 :实现了__iter__()方法的对象,或者说,是能返回一个迭代器的对象。

所有容器都是可迭代对象,但可迭代对象不一定是容器。

迭代器 :实现了__iter__()和__next__()方法的对象。它提供一个 next 方法,当你调用这个方法后,要么得到下一个对象,要么抛出 StopIteration 异常。

1、判断可迭代对象

通过 iter() 函数尝试转换,捕获 TypeError 判断:

python 复制代码
def is_iterable(param):  
    try:  
        iter(param)  
        return True  
    except TypeError:  
        return False  

# 测试:列表、字典等返回 True,数字返回 False  

生成器:更轻量的迭代器

1、核心优势

惰性计算 :仅在调用 next() 时生成元素,(比预先生成大列表 )节省内存。

简单语法 :使用生成器表达式((i for i in range(10)) )或 yield 关键字定义。

lua 复制代码
对于 yield,可以理解为:
函数运行到这一行的时候,程序会从这里暂停,然后跳出。跳到 next() 函数。
每次调用 `next(gen)` 时,暂停的程序,就会从 yield 这里向下继续执行;
2、基础用法
python 复制代码
# 1. 生成器表达式
gen = (i for i in range(3))
print(next(gen))  # 输出 0
print(next(gen))  # 输出 1
print(next(gen))  # 输出 2
print(next(gen))  # StopIteration

# 2. yield 关键字
def my_generator():
    yield 1
    yield 2
    yield 3


gen = my_generator()
print(next(gen))  # 输出 1
print(next(gen))  # 输出 2
print(next(gen))  # 输出 3
print(next(gen))  # StopIteration

实战应用

1、内存优化对比

生成器可以避免预存大量数据,适合处理超大序列:

python 复制代码
from pympler import asizeof

# 迭代器
large_list = [i for i in range(10**5)]

# 生成器
# 仅保存生成逻辑,内存大小不随数据量大小变化,内存占用极低
large_gen = (i for i in range(10**5))

# 输出:列表占用内存: 3907.21 KB
print(f"列表占用内存: {asizeof.asizeof(large_list) / 1024:.2f} KB")
# 输出:生成器占用内存: 0.45 KB
print(f"生成器占用内存: {asizeof.asizeof(large_gen) / 1024:.2f} KB")
2、复杂逻辑实现:验证数学公式

用生成器动态生成数列,验证等式 (1+2+...+n)² = 1³+2³+...+n³:

python 复制代码
# 使用生成器
def generator(k):  
    i = 1  
    while True:  
        yield i**k  
        i += 1  

gen_1 = generator(2)  # 生成 1,4,9...
gen_3 = generator(3)  # 生成 1³,2³,3³...  
3、算法简化:子序列判断

用生成器 + 迭代器,可以更简洁实现 "判断子序列" 逻辑:

LeetCode 题目:leetcode.com/problems/is...

python 复制代码
def is_subsequence(a, b):  
    b = iter(b)  # 转为迭代器  
    return all(i in b for i in a)  

# 测试:a = [1,3,5] 是 b = [1,2,3,4,5] 的子序列  
print(is_subsequence([1, 3, 5], [1, 2, 3, 4, 5]))  # True  
print(is_subsequence([1, 4, 3], [1, 2, 3, 4, 5]))  # False

高频面试题

01、可迭代对象和迭代器的区别?

markdown 复制代码
可迭代对象:实现 __iter__,可转为迭代器(如 list )。
迭代器:实现 __iter__ 和 __next__,支持 next() 逐个取元素。

02、生成器的 yield 有什么作用?

scss 复制代码
暂停函数执行,保留当前状态(如变量值 )。返回一个值给调用者。
下次 next() 调用时从暂停处继续执行。

03、生成器为什么能节省内存?

scss 复制代码
生成器是 "惰性计算",不预存所有元素,仅在调用 next() 时动态生成。
因此,内存占用远低于预先生成大列表的迭代器。

04、for 循环如何遍历可迭代对象?

scss 复制代码
for 循环自动将可迭代对象转为迭代器(调用 iter() )。
然后,循环调用 next(),直到捕获 StopIteration 异常退出。

05、哪些场景适合用生成器?

markdown 复制代码
1. 处理超大序列(如一亿条数据 ),避免内存溢出。
2. 实现动态生成逻辑(如无限数列、实时数据流 )。
3. 简化代码(如子序列判断、复杂数学验证 )。

06、生成器迭代结束后,继续调用 next() 会怎样?

复制代码
抛出 StopIteration 异常,提示迭代已结束。

-------- 写在最后 --------

关注我,每天1分钟,轻松懂 Python

我的同名公众号正在连载《FastAPI 开发实战》、《Python 核心技术》、《职场》。


点赞 :如果觉得有收获,点赞支持一下吧!

分享 :分享给身边同样对Python感兴趣的朋友!

关注我 :不要错过每一篇 Python 实战内容!


#Python #FastAPI #API #Web开发 #程序员 #编程教程 #效率提升 #装饰器

相关推荐
第九序言T3 小时前
Python 数据处理进阶(十八)批量处理同结构文件:一个文件夹一次跑完
开发语言·python·自动化·pandas·数据处理
Java后端的Ai之路4 小时前
CAS并发控制-从CPU指令到企业级乐观锁
vue.js·人工智能·python·cas·乐观锁
qq_426003964 小时前
UI自动化高频次登录login限流解决方案
python·ui·自动化
Sakura_j_h_4 小时前
EasyEDA PCB 快速设计Skills
c++·python·github
quantdash_cc5 小时前
如何验证历史行情的交易日期是否完整覆盖研究区间?
python·数据分析·pandas·量化交易·股票数据·quantdash
I Am a robert girl5 小时前
当智能体学会“串通”:从长程交互中读懂涌现式合谋
python·多智能体系统·多智能体协作·llm agent·涌现式合谋·对齐问题·激励机制设计
云和数据.ChenGuang6 小时前
光哥说Python RAG 系统需要哪些评估指标:从检索到生成的全链路评测指南
网络·人工智能·python·算法·langchain
专注仿真6 小时前
线性回归和逻辑回归算法详解
开发语言·人工智能·python·大模型训练·控制算法
wflynn7 小时前
GitHub 今日推荐|Edge0:让大号 MoE 模型在一台 Mac 上流式跑起来
python·开源·github
2601_967980118 小时前
python之用scapy分层解析pcap报文(Ethernet帧、IP数据包、TCP数据包、UDP数据包、Raw数据包)
python·scapy·pcap·协议分析·网络数据包