You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将生成器按指定大小分块?相关实现与内存疑问

用生成器替代列表实现分块迭代的问题与解决

原列表分块实现

基于列表的分块生成器代码如下:

list_values = [...]
gen = (
        list_values[pos : pos + bucket_size]
        for pos in range(0, len(list_values), bucket_size)
    )

问题:替换为生成器后的实现与疑问

若将list_values替换为生成器以降低内存占用,尝试用itertools.islice实现:

gen = (
        islice(list_values, pos, pos + bucket_size)
        for pos in range(0, len(list_values), bucket_size)
    )

但存在两个问题:

  1. 生成器无法调用len(list_values),该如何替代?
  2. 此场景下使用islice能否降低峰值内存占用?

问题1解答:替代len()的实现方式

生成器/迭代器是消耗型且无固定长度的,无法通过len()获取长度,因此不能用range控制分块次数。正确的做法是循环从迭代器中批量取元素,直到迭代器耗尽,可实现如下自定义生成器函数:

from itertools import islice

def chunk_generator(iterable, bucket_size):
    # 确保输入是迭代器(即使传入列表也转为迭代器)
    iterable = iter(iterable)
    while True:
        # 每次从迭代器中取最多bucket_size个元素
        chunk = list(islice(iterable, bucket_size))
        if not chunk:
            # 无元素时终止循环
            break
        yield chunk

原理说明

  • 迭代器是一次性消耗的,每次调用islice会自动推进原迭代器的位置,无需手动记录pos;
  • 循环直到islice返回的chunk为空,说明原迭代器已耗尽。

问题2解答:islice对峰值内存的影响

能有效降低峰值内存占用,原因如下:

  • 原列表分块方式:需要先将整个列表加载到内存,峰值内存等于整个列表的大小;
  • 生成器+islice方式:原迭代器按需生成元素,每次仅将当前分块的元素保留在内存中(若转成列表);若直接返回islice迭代器而非列表,内存占用会更低——因为不会一次性把分块内的所有元素加载到内存,而是遍历时分批获取。

内容的提问来源于stack exchange,提问作者An old man in the sea.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 16:10:32