Skip to main content
 首页 » 编程设计

python之从列表中生成循环批处理

2025年05月04日14lonelyxmas

基本上,我想根据给定列表 l 创建一个无限生成器批量大小为 batch_size .例如,如果我有 l = [1, 2, 3, 4, 5] 的列表和 batch_size = 2 , 我想生成 [1, 2] 的无限循环, [3, 4] , [5, 1] , [2, 3] , ...(类似于 itertool.circular 具有额外的批量大小)

我目前的方法如下,但还没有给出正确的解决方案,因为最后我只是在到达末尾时填充列表的第一个元素:

l = [1, 2, 3, 4, 5] 
 
def generator(l, batch_size=2): 
    while 1: 
        for i in range(0, len(l), batch_size): 
            batch = l[i:(i + batch_size)] 
            if len(batch) < batch_size: 
                batch.extend(l[0: batch_size - len(batch)]) 
            yield batch 
 
>> gen = generator(l, batch_size=2) 
>> next(gen) # [1, 2] 
>> next(gen) # [3, 4] 
>> next(gen) # [5, 1] 
>> next(gen) # [1, 2] << want [2, 3] instead 

有没有办法以循环的方式做到这一点?

请您参考如下方法:

是的,您基本上需要“take”和cycle的组合:

>>> def circle_batch(iterable, batchsize): 
...     it = itertools.cycle(iterable) 
...     while True: 
...         yield list(itertools.islice(it, batchsize)) 
... 
>>> l = [1, 2, 3, 4, 5] 
>>> c = circle_batch(l, 2) 
>>> next(c) 
[1, 2] 
>>> next(c) 
[3, 4] 
>>> next(c) 
[5, 1] 
>>> next(c) 
[2, 3] 
>>> next(c) 
[4, 5] 

来自recipes in the docs您会看到 take 是一个基本工具,因此使用它:

>>> def take(n, iterable): 
...     "Return first n items of the iterable as a list" 
...     return list(islice(iterable, n)) 
... 
>>> def cycle_batch(iterable, batchsize): 
...     it = itertools.cycle(iterable) 
...     while True: 
...         return take(batchsize, it) 
... 
>>> l = [1, 2, 3, 4, 5] 
>>> c = circle_batch(l, 2) 
>>> next(c) 
[1, 2] 
>>> next(c) 
[3, 4] 
>>> next(c) 
[5, 1] 
>>> next(c) 
[2, 3] 
>>> next(c) 
[4, 5] 
>>> next(c) 
[1, 2]