簡體   English   中英

從列表中讀取批處理

[英]Reading batches from a list wrapping around

我有以下情況。 說我有一個變量batch_size和一個名為data的列表。 我想從data提取batch_size元素,以便在結束時回繞。 換一種說法:

data =[1,2,3,4,5]
batch_size = 4
-> [1,2,3,4], [5,1,2,3], [4,5,1,2], ...

是否有一些不錯的慣用方式來返回像這樣的切片? 起始索引始終為batch_size * batchdata長度為模,但是如果batch_size * (batch+1)超出列表的長度,是否有一種從頭開始“換行”的簡單方法? 在這種情況下,我當然可以將兩個切片拼湊在一起,但是我希望有一些非常干凈的方法可以這樣做。

我所做的唯一假設是batch_size < len(data)

您可以使用itertools.cycleitertools.cyclegrouper食譜

import itertools

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return itertools.zip_longest(*args, fillvalue=fillvalue)

data = [1,2,3,4,5]
batch_size = 4
how_many_groups = 5

groups = grouper(itertools.cycle(data), batch_size)
chunks = [next(groups) for _ in range(how_many_groups)]

塊的結果是:

[(1, 2, 3, 4),
 (5, 1, 2, 3),
 (4, 5, 1, 2),
 (3, 4, 5, 1),
 (2, 3, 4, 5)]

因此,如果您實際需要這些列表,則必須將其強制轉換為[list(next(groups)) for ...]

您還可以使用來自collections模塊的deque ,對deque進行旋轉,如下例所示:

from collections import deque

def grouper(iterable, elements, rotations):
    if elements > len(iterable):
        return []

    b = deque(iterable)
    for _ in range(rotations):
        yield list(b)[:elements]
        b.rotate(1)


data = [1,2,3,4,5]
elements = 4
rotations = 5
final = list(grouper(data, elements, rotations))
print(final)

輸出:

[[1, 2, 3, 4], [5, 1, 2, 3], [4, 5, 1, 2], [3, 4, 5, 1], [2, 3, 4, 5]]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM