反復可能オブジェクトを一定サイズのチャンクに分割する方法 [重複] 質問する

反復可能オブジェクトを一定サイズのチャンクに分割する方法 [重複] 質問する

反復可能オブジェクトを入力として受け取り、反復可能オブジェクトの反復可能オブジェクトを返す「バッチ」関数が見つからないことに驚いています。

例えば:

for i in batch(range(0,10), 1): print i
[0]
[1]
...
[9]

または:

for i in batch(range(0,10), 3): print i
[0,1,2]
[3,4,5]
[6,7,8]
[9]

さて、私はかなりシンプルなジェネレーターを書きました。

def batch(iterable, n = 1):
   current_batch = []
   for item in iterable:
       current_batch.append(item)
       if len(current_batch) == n:
           yield current_batch
           current_batch = []
   if current_batch:
       yield current_batch

しかし、上記では私が期待していた結果は得られませんでした。

for x in   batch(range(0,10),3): print x
[0]
[0, 1]
[0, 1, 2]
[3]
[3, 4]
[3, 4, 5]
[6]
[6, 7]
[6, 7, 8]
[9]

つまり、私は何かを見逃しており、これはおそらく私が Python ジェネレーターを完全に理解していないことを示しているのでしょう。誰か私に正しい方向を指し示してくれませんか?

[編集: 結局、上記の動作は、Python 自体ではなく、ipython 内で実行した場合にのみ発生することに気付きました]

ベストアンサー1

これはおそらくより効率的(より速い)

def batch(iterable, n=1):
    l = len(iterable)
    for ndx in range(0, l, n):
        yield iterable[ndx:min(ndx + n, l)]

for x in batch(range(0, 10), 3):
    print x

リストを使用した例

data = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # list of data 

for x in batch(data, 3):
    print(x)

# Output

[0, 1, 2]
[3, 4, 5]
[6, 7, 8]
[9, 10]

新しいリストの作成を回避します。

おすすめ記事