バッチ処理のために入力ストリームをチャンクしたい。入力リストまたはジェネレーターが与えられると、
x_in = [1, 2, 3, 4, 5, 6 ...]
その入力のチャンクを返す関数が必要です。と言う、もしそうならchunk_size=4
、
x_chunked = [[1, 2, 3, 4], [5, 6, ...], ...]
これは私が何度も繰り返していることであり、自分で書くよりも標準的な方法があるのではないかと考えていました。私は何かが欠けていitertools
ますか?enumerate
(とで問題を解決することはできますgroupby
が、それは不格好に感じます。)誰かが実装を見たい場合は、ここにあります、
def chunk_input_stream(input_stream, chunk_size):
"""partition a generator in a streaming fashion"""
assert chunk_size >= 1
accumulator = []
for x in input_stream:
accumulator.append(x)
if len(accumulator) == chunk_size:
yield accumulator
accumulator = []
if accumulator:
yield accumulator
編集
kreativiteaの答えに触発されて、これがでの解決策islice
です。これは簡単で、事後フィルタリングを必要としません。
from itertools import islice
def chunk_input_stream(input_stream, chunk_size):
while True:
chunk = list(islice(input_stream, chunk_size))
if chunk:
yield chunk
else:
return
# test it with list(chunk_input_stream(iter([1, 2, 3, 4]), 3))