リストをどのように均等なサイズのチャンクに分割しますか?

2407
jespern 2008-11-24 02:15.

任意の長さのリストがあり、それを同じサイズのチャンクに分割して操作する必要があります。これを行うには、カウンターと2つのリストを保持するなど、いくつかの明白な方法があります。2番目のリストがいっぱいになったら、それを最初のリストに追加し、次のラウンドのデータのために2番目のリストを空にしますが、これは潜在的に非常にコストがかかります。

ジェネレータを使用するなど、任意の長さのリストに対して、これに対する良い解決策があるかどうか疑問に思いました。

何か役に立つものを探していましたitertoolsが、明らかに役立つものは見つかりませんでした。しかし、それを見逃したかもしれません。

関連する質問:リストをチャンクで反復する最も「pythonic」な方法は何ですか?

30 answers

3400
Ned Batchelder 2008-11-24 02:33.

必要なチャンクを生成するジェネレーターは次のとおりです。

def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in range(0, len(lst), n):
        yield lst[i:i + n]

import pprint
pprint.pprint(list(chunks(range(10, 75), 10)))
[[10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
 [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
 [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
 [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
 [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
 [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
 [70, 71, 72, 73, 74]]

Python 2を使用している場合は、次のxrange()代わりに使用する必要がありますrange()

def chunks(lst, n):
    """Yield successive n-sized chunks from lst."""
    for i in xrange(0, len(lst), n):
        yield lst[i:i + n]

また、関数を作成する代わりにリスト内包表記を使用することもできますが、コードを理解しやすくするために、このような操作を名前付き関数にカプセル化することをお勧めします。Python 3:

[lst[i:i + n] for i in range(0, len(lst), n)]

Python 2バージョン:

[lst[i:i + n] for i in xrange(0, len(lst), n)]
577
oremj 2009-11-18 10:17.

超シンプルなものが必要な場合:

def chunks(l, n):
    n = max(1, n)
    return (l[i:i+n] for i in range(0, len(l), n))

Python2.xの場合のxrange()代わりに使用するrange()

309
tzot 2008-11-24 05:48.

(古い)Pythonドキュメント(itertoolsのレシピ)から直接:

from itertools import izip, chain, repeat

def grouper(n, iterable, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return izip(*[chain(iterable, repeat(padvalue, n-1))]*n)

JFSebastianによって提案された現在のバージョン:

#from itertools import izip_longest as zip_longest # for Python 2.x
from itertools import zip_longest # for Python 3.x
#from six.moves import zip_longest # for both (uses the six compat library)

def grouper(n, iterable, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return zip_longest(*[iter(iterable)]*n, fillvalue=padvalue)

Guidoのタイムマシンは、機能し、機能し、機能し、機能し、再び機能したと思います。

これらのソリューションが機能するのは、[iter(iterable)]*n(または以前のバージョンの同等のものが)リスト内で繰り返し1つのイテレーターを作成nするためです。izip_longest次に、「各」イテレータのラウンドロビンを効果的に実行します。これは同じイテレータであるため、そのような呼び出しごとに進められ、その結果、そのようなzipラウンドロビンごとに1つのタプルのnアイテムが生成されます。

262
Moj 2013-06-05 22:54.

私はこれがちょっと古いことを知っていますが、まだ誰も言及していませんnumpy.array_split

import numpy as np

lst = range(50)
np.array_split(lst, 5)
# [array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
#  array([10, 11, 12, 13, 14, 15, 16, 17, 18, 19]),
#  array([20, 21, 22, 23, 24, 25, 26, 27, 28, 29]),
#  array([30, 31, 32, 33, 34, 35, 36, 37, 38, 39]),
#  array([40, 41, 42, 43, 44, 45, 46, 47, 48, 49])]
176
senderle 2014-02-27 05:02.

iterの2つの引数形式を使用することを誰も考えていないことに驚いています:

from itertools import islice

def chunk(it, size):
    it = iter(it)
    return iter(lambda: tuple(islice(it, size)), ())

デモ:

>>> list(chunk(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13)]

これは任意の反復可能で機能し、遅延出力を生成します。イテレータではなくタプルを返しますが、それでもある程度のエレガンスがあると思います。また、パディングもしません。パディングが必要な場合は、上記の単純なバリエーションで十分です。

from itertools import islice, chain, repeat

def chunk_pad(it, size, padval=None):
    it = chain(iter(it), repeat(padval))
    return iter(lambda: tuple(islice(it, size)), (padval,) * size)

デモ:

>>> list(chunk_pad(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, None)]
>>> list(chunk_pad(range(14), 3, 'a'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 'a')]

izip_longestベースのソリューションと同様に、上記は常にパッドです。私の知る限り、オプションでパディングする関数の1行または2行のitertoolsレシピはありません。上記の2つのアプローチを組み合わせることにより、これはかなり近くなります。

_no_padding = object()

def chunk(it, size, padval=_no_padding):
    if padval == _no_padding:
        it = iter(it)
        sentinel = ()
    else:
        it = chain(iter(it), repeat(padval))
        sentinel = (padval,) * size
    return iter(lambda: tuple(islice(it, size)), sentinel)

デモ:

>>> list(chunk(range(14), 3))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13)]
>>> list(chunk(range(14), 3, None))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, None)]
>>> list(chunk(range(14), 3, 'a'))
[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11), (12, 13, 'a')]

これは、オプションのパディングを提供する提案された最短のチャンカーだと思います。

Tomasz Gandorが観察したように、2つのパディングチャンカーは、パッド値の長いシーケンスに遭遇すると、予期せず停止します。これは、その問題を合理的な方法で回避する最終的なバリエーションです。

_no_padding = object()
def chunk(it, size, padval=_no_padding):
    it = iter(it)
    chunker = iter(lambda: tuple(islice(it, size)), ())
    if padval == _no_padding:
        yield from chunker
    else:
        for ch in chunker:
            yield ch if len(ch) == size else ch + (padval,) * (size - len(ch))

デモ:

>>> list(chunk([1, 2, (), (), 5], 2))
[(1, 2), ((), ()), (5,)]
>>> list(chunk([1, 2, None, None, 5], 2, None))
[(1, 2), (None, None), (5, None)]
99
Markus Jarderot 2008-11-24 02:41.

これは、任意の反復可能オブジェクトで動作するジェネレーターです。

def split_seq(iterable, size):
    it = iter(iterable)
    item = list(itertools.islice(it, size))
    while item:
        yield item
        item = list(itertools.islice(it, size))

例:

>>> import pprint
>>> pprint.pprint(list(split_seq(xrange(75), 10)))
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
 [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
 [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
 [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
 [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
 [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
 [70, 71, 72, 73, 74]]
55
Tomasz Wysocki 2010-06-27 09:10.
def chunk(input, size):
    return map(None, *([iter(input)] * size))
53
lebenf 2010-07-12 21:58.

シンプルでありながらエレガント

l = range(1, 1000)
print [l[x:x+10] for x in xrange(0, len(l), 10)]

または必要に応じて:

def chunks(l, n): return [l[x: x+n] for x in xrange(0, len(l), n)]
chunks(l, 10)
43
Aaron Hall 2014-02-14 13:07.

ここで他の答えの批評:

これらの回答はどれも均等なサイズのチャンクではなく、すべて最後にラントチャンクを残すため、完全にバランスが取れていません。これらの機能を使用して作業を分散している場合、1つが他の機能よりもかなり早く終了する可能性が組み込まれているため、他の機能が懸命に作業を続けている間は何もしません。

たとえば、現在の上位の回答は次のように終わります。

[60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
[70, 71, 72, 73, 74]]

私は最後にそのラントが嫌いです!

のような他のものlist(grouper(3, xrange(7)))は、chunk(xrange(7), 3)両方とも戻ります:[(0, 1, 2), (3, 4, 5), (6, None, None)]Noneさんはちょうどパディング、そして私の意見ではなく、洗練されています。それらは反復可能オブジェクトを均等にチャンクしていません。

なぜこれらをうまく分割できないのですか?

私の解決策

ここではバランスの取れた解決策だ、私は生産に使用していた機能(置き換えるためのPython 3での注意から適応xrangeしてrange):

def baskets_from(items, maxbaskets=25):
    baskets = [[] for _ in xrange(maxbaskets)] # in Python 3 use range
    for i, item in enumerate(items):
        baskets[i % maxbaskets].append(item)
    return filter(None, baskets) 

そして、リストに入れれば同じことをするジェネレーターを作成しました。

def iter_baskets_from(items, maxbaskets=3):
    '''generates evenly balanced baskets from indexable iterable'''
    item_count = len(items)
    baskets = min(item_count, maxbaskets)
    for x_i in xrange(baskets):
        yield [items[y_i] for y_i in xrange(x_i, item_count, baskets)]

そして最後に、上記のすべての関数が(与えられたとおりに)連続した順序で要素を返すことがわかります。

def iter_baskets_contiguous(items, maxbaskets=3, item_count=None):
    '''
    generates balanced baskets from iterable, contiguous contents
    provide item_count if providing a iterator that doesn't support len()
    '''
    item_count = item_count or len(items)
    baskets = min(item_count, maxbaskets)
    items = iter(items)
    floor = item_count // baskets 
    ceiling = floor + 1
    stepdown = item_count % baskets
    for x_i in xrange(baskets):
        length = ceiling if x_i < stepdown else floor
        yield [items.next() for _ in xrange(length)]

出力

それらをテストするには:

print(baskets_from(xrange(6), 8))
print(list(iter_baskets_from(xrange(6), 8)))
print(list(iter_baskets_contiguous(xrange(6), 8)))
print(baskets_from(xrange(22), 8))
print(list(iter_baskets_from(xrange(22), 8)))
print(list(iter_baskets_contiguous(xrange(22), 8)))
print(baskets_from('ABCDEFG', 3))
print(list(iter_baskets_from('ABCDEFG', 3)))
print(list(iter_baskets_contiguous('ABCDEFG', 3)))
print(baskets_from(xrange(26), 5))
print(list(iter_baskets_from(xrange(26), 5)))
print(list(iter_baskets_contiguous(xrange(26), 5)))

印刷するもの:

[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0], [1], [2], [3], [4], [5]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 8, 16], [1, 9, 17], [2, 10, 18], [3, 11, 19], [4, 12, 20], [5, 13, 21], [6, 14], [7, 15]]
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13, 14], [15, 16, 17], [18, 19], [20, 21]]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'D', 'G'], ['B', 'E'], ['C', 'F']]
[['A', 'B', 'C'], ['D', 'E'], ['F', 'G']]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[0, 5, 10, 15, 20, 25], [1, 6, 11, 16, 21], [2, 7, 12, 17, 22], [3, 8, 13, 18, 23], [4, 9, 14, 19, 24]]
[[0, 1, 2, 3, 4, 5], [6, 7, 8, 9, 10], [11, 12, 13, 14, 15], [16, 17, 18, 19, 20], [21, 22, 23, 24, 25]]

隣接するジェネレーターは、他の2つと同じ長さのパターンでチャンクを提供しますが、項目はすべて順番に並んでおり、離散要素のリストを分割できるのと同じくらい均等に分割されていることに注意してください。

41
Noich 2015-03-13 02:36.

私はこの質問の複製で最も素晴らしいPython風の答えを見ました:

from itertools import zip_longest

a = range(1, 16)
i = iter(a)
r = list(zip_longest(i, i, i))
>>> print(r)
[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, 15)]

任意のnに対してnタプルを作成できます。の場合a = range(1, 15)、結果は次のようになります。

[(1, 2, 3), (4, 5, 6), (7, 8, 9), (10, 11, 12), (13, 14, None)]

リストが均等に分割されている場合は、交換することができるzip_longestzipそうでないトリプレットは、(13, 14, None)失われてしまいます。上記ではPython3が使用されています。Python 2の場合は、を使用しますizip_longest

38
atzz 2008-11-24 02:40.

リストのサイズがわかっている場合:

def SplitList(mylist, chunk_size):
    return [mylist[offs:offs+chunk_size] for offs in range(0, len(mylist), chunk_size)]

そうでない場合(イテレータ):

def IterChunks(sequence, chunk_size):
    res = []
    for item in sequence:
        res.append(item)
        if len(res) >= chunk_size:
            yield res
            res = []
    if res:
        yield res  # yield the last, incomplete, portion

後者の場合、シーケンスに指定されたサイズのチャンクが常に整数で含まれている(つまり、最後のチャンクが不完全でない)ことが確実であれば、より美しい方法で言い換えることができます。

21
ninjagecko 2011-04-19 19:27.

たとえば、チャンクサイズが3の場合、次のことができます。

zip(*[iterable[i::3] for i in range(3)]) 

ソース: http://code.activestate.com/recipes/303060-group-a-list-into-sequential-n-tuples/

チャンクサイズが「3」などの入力可能な固定数であり、変更されない場合にこれを使用します。

20
zach 2013-11-21 10:55.

バーチャルツールのライブラリがありpartition、この機能を:

from toolz.itertoolz.core import partition

list(partition(2, [1, 2, 3, 4]))
[(1, 2), (3, 4)]
20
Riaz Rizvi 2015-12-17 11:42.
[AA[i:i+SS] for i in range(len(AA))[::SS]]

AAが配列の場合、SSはチャンクサイズです。例えば:

>>> AA=range(10,21);SS=3
>>> [AA[i:i+SS] for i in range(len(AA))[::SS]]
[[10, 11, 12], [13, 14, 15], [16, 17, 18], [19, 20]]
# or [range(10, 13), range(13, 16), range(16, 19), range(19, 21)] in py3
17
nikipore 2013-10-09 20:17.

tzotとJFSebastianによって提案されたPythondocのバージョンが大好きですが、2つの欠点があります。

  • あまり明確ではありません
  • 私は通常、最後のチャンクに塗りつぶし値を入れたくありません

私はこれを私のコードでよく使用しています:

from itertools import islice

def chunks(n, iterable):
    iterable = iter(iterable)
    while True:
        yield tuple(islice(iterable, n)) or iterable.next()

更新:レイジーチャンクバージョン:

from itertools import chain, islice

def chunks(n, iterable):
   iterable = iter(iterable)
   while True:
       yield chain([next(iterable)], islice(iterable, n-1))
16
nirvana-msu 2019-12-11 01:59.

代入式のPython 3.8で、それはとてもいいようになります。

import itertools

def batch(iterable, size):
    it = iter(iterable)
    while item := list(itertools.islice(it, size)):
        yield item

これは、リストだけでなく、任意の反復可能オブジェクトに対して機能します。

>>> import pprint
>>> pprint.pprint(list(batch(range(75), 10)))
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
 [10, 11, 12, 13, 14, 15, 16, 17, 18, 19],
 [20, 21, 22, 23, 24, 25, 26, 27, 28, 29],
 [30, 31, 32, 33, 34, 35, 36, 37, 38, 39],
 [40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
 [50, 51, 52, 53, 54, 55, 56, 57, 58, 59],
 [60, 61, 62, 63, 64, 65, 66, 67, 68, 69],
 [70, 71, 72, 73, 74]]
15
Alex T 2018-01-07 22:58.

私はさまざまなアプローチのパフォーマンスに興味がありました、そしてここにそれがあります:

Python3.5.1でテスト済み

import time
batch_size = 7
arr_len = 298937

#---------slice-------------

print("\r\nslice")
start = time.time()
arr = [i for i in range(0, arr_len)]
while True:
    if not arr:
        break

    tmp = arr[0:batch_size]
    arr = arr[batch_size:-1]
print(time.time() - start)

#-----------index-----------

print("\r\nindex")
arr = [i for i in range(0, arr_len)]
start = time.time()
for i in range(0, round(len(arr) / batch_size + 1)):
    tmp = arr[batch_size * i : batch_size * (i + 1)]
print(time.time() - start)

#----------batches 1------------

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

print("\r\nbatches 1")
arr = [i for i in range(0, arr_len)]
start = time.time()
for x in batch(arr, batch_size):
    tmp = x
print(time.time() - start)

#----------batches 2------------

from itertools import islice, chain

def batch(iterable, size):
    sourceiter = iter(iterable)
    while True:
        batchiter = islice(sourceiter, size)
        yield chain([next(batchiter)], batchiter)


print("\r\nbatches 2")
arr = [i for i in range(0, arr_len)]
start = time.time()
for x in batch(arr, batch_size):
    tmp = x
print(time.time() - start)

#---------chunks-------------
def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[i:i + n]
print("\r\nchunks")
arr = [i for i in range(0, arr_len)]
start = time.time()
for x in chunks(arr, batch_size):
    tmp = x
print(time.time() - start)

#-----------grouper-----------

from itertools import zip_longest # for Python 3.x
#from six.moves import zip_longest # for both (uses the six compat library)

def grouper(iterable, n, padvalue=None):
    "grouper(3, 'abcdefg', 'x') --> ('a','b','c'), ('d','e','f'), ('g','x','x')"
    return zip_longest(*[iter(iterable)]*n, fillvalue=padvalue)

arr = [i for i in range(0, arr_len)]
print("\r\ngrouper")
start = time.time()
for x in grouper(arr, batch_size):
    tmp = x
print(time.time() - start)

結果:

slice
31.18285083770752

index
0.02184295654296875

batches 1
0.03503894805908203

batches 2
0.22681021690368652

chunks
0.019841909408569336

grouper
0.006506919860839844
14
Art B 2015-07-02 21:32.

コード:

def split_list(the_list, chunk_size):
    result_list = []
    while the_list:
        result_list.append(the_list[:chunk_size])
        the_list = the_list[chunk_size:]
    return result_list

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

print split_list(a_list, 3)

結果:

[[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
12
mazieres 2015-11-04 13:10.

この時点で、万が一の場合に備えて再帰ジェネレータが必要だと思います...

Python 2の場合:

def chunks(li, n):
    if li == []:
        return
    yield li[:n]
    for e in chunks(li[n:], n):
        yield e

Python 3の場合:

def chunks(li, n):
    if li == []:
        return
    yield li[:n]
    yield from chunks(li[n:], n)

また、大規模なエイリアンの侵入の場合、装飾された再帰ジェネレータが便利になる可能性があります。

def dec(gen):
    def new_gen(li, n):
        for e in gen(li, n):
            if e == []:
                return
            yield e
    return new_gen

@dec
def chunks(li, n):
    yield li[:n]
    for e in chunks(li[n:], n):
        yield e
12
Moinuddin Quadri 2017-01-28 13:12.

ライブラリのget_chunks機能を次のように使用することもできますutilspie

>>> from utilspie import iterutils
>>> a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

>>> list(iterutils.get_chunks(a, 5))
[[1, 2, 3, 4, 5], [6, 7, 8, 9]]

utilspiepip経由でインストールできます:

sudo pip install utilspie

免責事項:私はutilspieライブラリの作成者です

10
pylang 2018-08-26 15:40.

追加のアプローチのリストは次のとおりです。

与えられた

import itertools as it
import collections as ct

import more_itertools as mit


iterable = range(11)
n = 3

コード

標準ライブラリ

list(it.zip_longest(*[iter(iterable)] * n))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

d = {}
for i, x in enumerate(iterable):
    d.setdefault(i//n, []).append(x)

list(d.values())
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

dd = ct.defaultdict(list)
for i, x in enumerate(iterable):
    dd[i//n].append(x)

list(dd.values())
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

more_itertools+

list(mit.chunked(iterable, n))
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10]]

list(mit.sliced(iterable, n))
# [range(0, 3), range(3, 6), range(6, 9), range(9, 11)]

list(mit.grouper(n, iterable))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

list(mit.windowed(iterable, len(iterable)//n, step=n))
# [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, None)]

参考文献

  • zip_longest(関連記事、関連投稿)
  • setdefault (順序付けられた結果にはPython 3.6以降が必要です)
  • collections.defaultdict (順序付けられた結果にはPython 3.6以降が必要です)
  • more_itertools.chunked(関連記事)
  • more_itertools.sliced
  • more_itertools.grouper(関連記事)
  • more_itertools.windowedstagger、も参照してくださいzip_offset

+ itertoolsレシピなどを実装するサードパーティライブラリ。> pip install more_itertools

9
Ranaivo 2015-03-01 10:05.

別のより明示的なバージョン。

def chunkList(initialList, chunkSize):
    """
    This function chunks a list into sub lists 
    that have a length equals to chunkSize.

    Example:
    lst = [3, 4, 9, 7, 1, 1, 2, 3]
    print(chunkList(lst, 3)) 
    returns
    [[3, 4, 9], [7, 1, 1], [2, 3]]
    """
    finalList = []
    for i in range(0, len(initialList), chunkSize):
        finalList.append(initialList[i:i+chunkSize])
    return finalList
8
slav0nic 2008-11-24 02:51.

ええ、1行バージョン

In [48]: chunk = lambda ulist, step:  map(lambda i: ulist[i:i+step],  xrange(0, len(ulist), step))

In [49]: chunk(range(1,100), 10)
Out[49]: 
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 [11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
 [21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
 [31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
 [41, 42, 43, 44, 45, 46, 47, 48, 49, 50],
 [51, 52, 53, 54, 55, 56, 57, 58, 59, 60],
 [61, 62, 63, 64, 65, 66, 67, 68, 69, 70],
 [71, 72, 73, 74, 75, 76, 77, 78, 79, 80],
 [81, 82, 83, 84, 85, 86, 87, 88, 89, 90],
 [91, 92, 93, 94, 95, 96, 97, 98, 99]]
8
Corey Goldberg 2008-11-25 06:56.
def split_seq(seq, num_pieces):
    start = 0
    for i in xrange(num_pieces):
        stop = start + len(seq[i::num_pieces])
        yield seq[start:stop]
        start = stop

使用法:

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

for seq in split_seq(seq, 3):
    print seq
8
Mars 2010-02-16 19:49.

大きなリストに適したlen()を呼び出さずに:

def splitter(l, n):
    i = 0
    chunk = l[:n]
    while chunk:
        yield chunk
        i += n
        chunk = l[i:i+n]

そして、これは反復可能です:

def isplitter(l, n):
    l = iter(l)
    chunk = list(islice(l, n))
    while chunk:
        yield chunk
        chunk = list(islice(l, n))

上記の機能的な味:

def isplitter2(l, n):
    return takewhile(bool,
                     (tuple(islice(start, n))
                            for start in repeat(iter(l))))

または:

def chunks_gen_sentinel(n, seq):
    continuous_slices = imap(islice, repeat(iter(seq)), repeat(0), repeat(n))
    return iter(imap(tuple, continuous_slices).next,())

または:

def chunks_gen_filter(n, seq):
    continuous_slices = imap(islice, repeat(iter(seq)), repeat(0), repeat(n))
    return takewhile(bool,imap(tuple, continuous_slices))
7
macm 2013-02-19 03:31.

このリファレンスを参照してください

>>> orange = range(1, 1001)
>>> otuples = list( zip(*[iter(orange)]*10))
>>> print(otuples)
[(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), ... (991, 992, 993, 994, 995, 996, 997, 998, 999, 1000)]
>>> olist = [list(i) for i in otuples]
>>> print(olist)
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ..., [991, 992, 993, 994, 995, 996, 997, 998, 999, 1000]]
>>> 

Python3

7
vishes_shell 2016-11-04 09:10.

ここでみんながイテレータについて話しているので。boltonsそのための完璧な方法がありiterutils.chunked_iterます。

from boltons import iterutils

list(iterutils.chunked_iter(list(range(50)), 11))

出力:

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
 [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21],
 [22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32],
 [33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43],
 [44, 45, 46, 47, 48, 49]]

しかし、あなたが記憶に憐れみを持ちたくないのであれば、あなたは昔ながらの方法を使っlistて、そもそもiterutils.chunked

6
robert king 2012-02-13 18:50.
def chunks(iterable,n):
    """assumes n is an integer>0
    """
    iterable=iter(iterable)
    while True:
        result=[]
        for i in range(n):
            try:
                a=next(iterable)
            except StopIteration:
                break
            else:
                result.append(a)
        if result:
            yield result
        else:
            break

g1=(i*i for i in range(10))
g2=chunks(g1,3)
print g2
'<generator object chunks at 0x0337B9B8>'
print list(g2)
'[[0, 1, 4], [9, 16, 25], [36, 49, 64], [81]]'
6
schwater 2011-05-04 06:27.

matplotlib.cbookピースの使用を検討してください

例えば:

import matplotlib.cbook as cbook
segments = cbook.pieces(np.arange(20), 3)
for s in segments:
     print s
6
AdvilUser 2015-07-16 13:27.
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
CHUNK = 4
[a[i*CHUNK:(i+1)*CHUNK] for i in xrange((len(a) + CHUNK - 1) / CHUNK )]

Related questions

MORE COOL STUFF

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire は、彼女が息子の Shelby Blackstock と共有する「楽しい」クリスマスの伝統を明らかにしました:「私たちはたくさん笑います」

Reba McEntire が息子の Shelby Blackstock と共有しているクリスマスの伝統について学びましょう。

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルは、自然な髪のスタイリングをめぐってマライア・キャリーと結ばれました

メーガン・マークルとマライア・キャリーが自然な髪の上でどのように結合したかについて、メーガンの「アーキタイプ」ポッドキャストのエピソードで学びましょう.

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子は家族との関係を修復できるという「希望を持っている」:「彼は父親と兄弟を愛している」

ハリー王子が家族、特にチャールズ王とウィリアム王子との関係について望んでいると主張したある情報源を発見してください。

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドは、パニックに陥った休暇の瞬間に、彼女がジャッド家の家長であることを認識しました

ワイノナ・ジャッドが、母親のナオミ・ジャッドが亡くなってから初めての感謝祭のお祝いを主催しているときに、彼女が今では家長であることをどのように認識したかを学びましょう.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

世界最小のマルチツールを15ドルでキーチェーンに追加

世界最小のマルチツールを15ドルでキーチェーンに追加

爪| $ 15 | マルボロ&ケインザクロー| $ 15 | Malboro&Kane世界最小のマルチツールであるTheClawをたった15ドルで手に入れましょう。男の子と一緒に冷たいものを割って開けたり、ネジを締めたり、Amazonパッケージを細断したりする場合でも、この悪い男の子はこれまでで最も便利な製品の1つです。

ワンダーウーマンの続編の悪役についてのより多くの噂

ワンダーウーマンの続編の悪役についてのより多くの噂

ワンダーウーマンとしてのガル・ガドット。WaywardPinesは正式に終了しました。

42,000試合で作られた球がスローモーションで燃えるのを見るのは魅力的な光景です

42,000試合で作られた球がスローモーションで燃えるのを見るのは魅力的な光景です

人が2つのマッチを接着するように導くものは何ですか?何があなたをマッチに打ち続け、構造が湾曲していることを発見するのですか?42,000のボールを作るまで、試合を続けなければならない理由は何ですか?しかし、何よりも、これほど魅力的なショーである可能性はどのようにありますか?私はあなたをだますつもりはありません、次に私たちがあなたに残すのは、あなたや私のような人が自由な時間を過ごすことを決定するビデオですボールを作るために必要な試合数を確認します(答えは42です。

サクラメントビーが1950万人のカリフォルニア州の有権者記録を漏らし、ハッカーによって即座に侵害された

サクラメントビーが1950万人のカリフォルニア州の有権者記録を漏らし、ハッカーによって即座に侵害された

写真:AP先月、カリフォルニアの地元新聞が1,900万件以上の有権者記録をオンラインで公開しました。Gizmodoは今週、明らかなランサムウェア攻撃中にレコードが侵害されたことを確認しました。

米国のフィギュア スケートは、チーム イベントでの最終決定の欠如に「苛立ち」、公正な裁定を求める

米国のフィギュア スケートは、チーム イベントでの最終決定の欠如に「苛立ち」、公正な裁定を求める

ロシアのフィギュアスケーター、カミラ・バリエバが関与したドーピング事件が整理されているため、チームは2022年北京冬季オリンピックで獲得したメダルを待っています。

Amazonの買い物客は、わずか10ドルのシルクの枕カバーのおかげで、「甘やかされた赤ちゃんのように」眠れると言っています

Amazonの買い物客は、わずか10ドルのシルクの枕カバーのおかげで、「甘やかされた赤ちゃんのように」眠れると言っています

何千人ものAmazonの買い物客がMulberry Silk Pillowcaseを推奨しており、現在販売中. シルクの枕カバーにはいくつかの色があり、髪を柔らかく肌を透明に保ちます。Amazonで最大46%オフになっている間にシルクの枕カバーを購入してください

パデュー大学の教授が覚醒剤を扱った疑いで逮捕され、女性に性的好意を抱かせる

パデュー大学の教授が覚醒剤を扱った疑いで逮捕され、女性に性的好意を抱かせる

ラファイエット警察署は、「不審な男性が女性に近づいた」という複数の苦情を受けて、12 月にパデュー大学の教授の捜査を開始しました。

コンセプト ドリフト: AI にとって世界の変化は速すぎる

コンセプト ドリフト: AI にとって世界の変化は速すぎる

私たちの周りの世界と同じように、言語は常に変化しています。以前の時代では、言語の変化は数年または数十年にわたって発生していましたが、現在では数日または数時間で変化する可能性があります。

SF攻撃で91歳のアジア人女性が殴られ、コンクリートに叩きつけられた

犯罪擁護派のオークランドが暴力犯罪者のロミオ・ロレンゾ・パーハムを釈放

SF攻撃で91歳のアジア人女性が殴られ、コンクリートに叩きつけられた

認知症を患っている 91 歳のアジア人女性が最近、47 番街のアウター サンセット地区でロメオ ロレンゾ パーハムに襲われました。伝えられるところによると、被害者はサンフランシスコの通りを歩いていたところ、容疑者に近づき、攻撃を受け、暴行を受けました。

ℝ

“And a river went out of Eden to water the garden, and from thence it was parted and became into four heads” Genesis 2:10. ? The heart is located in the middle of the thoracic cavity, pointing eastward.

メリック・ガーランドはアメリカに失敗しましたか?

バイデン大統領の任期の半分以上です。メリック・ガーランドは何を待っていますか?

メリック・ガーランドはアメリカに失敗しましたか?

人々にチャンスを与えることは、人生で少し遅すぎると私は信じています。寛大に。

Language