[英]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 * batch
以data
長度為模,但是如果batch_size * (batch+1)
超出列表的長度,是否有一種從頭開始“換行”的簡單方法? 在這種情況下,我當然可以將兩個切片拼湊在一起,但是我希望有一些非常干凈的方法可以這樣做。
我所做的唯一假設是batch_size < len(data)
。
您可以使用itertools.cycle
和itertools.cycle
的grouper
食譜
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.