batched() 更省内存因其是惰性迭代器,不预加载整个输入;而 list[i:i+n] 会先将生成器等全展开为内存列表,易触发 memoryerror 或超时。

batched() 为什么比 list[i:i+n] 更省内存
因为 batched() 是惰性迭代器,不预加载整个输入;而 list(it)[i:i+n] 会先调用 list() 把生成器、文件行或数据库游标全展开成内存列表,极易触发 MemoryError 或阻塞超时。
常见错误现象:
- 读取千万行日志时,
list(open("big.log"))直接卡死或崩溃 - 用
islice()手写循环但忘了重置迭代器,导致漏掉最后一组 - 误把
batched()结果传给需要list的 API(如某些 pandas 构造函数),报TypeError: expected list, got tuple
batched() 返回 tuple 而不是 list 的实际影响
它返回的是 tuple,不可变、可哈希,适合做字典键或放进集合;但如果你写了 batch.append(x) 就会立刻报 AttributeError。
使用场景差异:
- 喂给数据库
executemany():多数驱动要求每行是tuple,刚好匹配,无需转换 - 传给
pandas.DataFrame():需显式转成list(batch)或用pd.DataFrame(list(batch)) - 做缓存 key:直接用
cache[key] = batch没问题;若用list就会报unhashable type
末尾不足 batch_size 时 batched() 真实行为
batched() 默认保留最后一组,哪怕只剩一个元素,也返回长度为 1 的 tuple。它既不丢弃、也不填充、更不报错。
但你“看不到最后一组”,往往是因为:
- 在
for batch in batched(...)循环里加了break或提前return - 源迭代器本身被其他逻辑中途耗尽(比如文件句柄已关闭)
- 调试时写了
print(list(batched(...)))—— 这会强制展开全部批次,失去流式意义,且可能 OOM
batched() 在真实大迭代器下的关键注意事项
光用 batched() 不够,下游消费节奏必须同步控制:
- 写入文件时,别把整批
tuple拼成一个超长字符串再f.write();应逐行write()或控制BATCH_SIZE在 1000–5000 之间(实测 5000 行约 200 KB 字符串,平衡吞吐与内存) - 插入数据库前,确认是否支持
executemany();不支持的话,得改用单条execute()+ 批量 commit - 和
more-itertools.chunked()混用要小心:前者返回list,后者返回tuple,类型错位会导致下游逻辑静默失败
最容易被忽略的是:它只存在于 Python 3.12+,旧版本必须降级用 islice() 手写或引入第三方包;而且它不接受 fillvalue,补全逻辑得自己 wrap。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











