外部パッケージの使用を気にしない場合はiteration_utilities.grouper、1から使用できます。(シーケンスだけでなく)すべての反復可能オブジェクトをサポートします。iteration_utilties 
from iteration_utilities import grouper
seq = list(range(20))
for group in grouper(seq, 4):
    print(group)
印刷する:
(0, 1, 2, 3)
(4, 5, 6, 7)
(8, 9, 10, 11)
(12, 13, 14, 15)
(16, 17, 18, 19)
長さがグループサイズの倍数ではない場合、最後のグループを埋める(不完全な最後のグループ)または切り捨てる(不完全な最後のグループを破棄する)もサポートします。
from iteration_utilities import grouper
seq = list(range(17))
for group in grouper(seq, 4):
    print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
# (16,)
for group in grouper(seq, 4, fillvalue=None):
    print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
# (16, None, None, None)
for group in grouper(seq, 4, truncate=True):
    print(group)
# (0, 1, 2, 3)
# (4, 5, 6, 7)
# (8, 9, 10, 11)
# (12, 13, 14, 15)
ベンチマーク
また、前述のアプローチのいくつかの実行時間を比較することも決定しました。これは、さまざまなサイズのリストに基づいて「10」要素のグループにグループ化された対数-対数プロットです。定性的な結果の場合:低いほど速くなります:

少なくともこのベンチマークでは、iteration_utilities.grouperパフォーマンスが最高です。続いてクレイズのアプローチ。
ベンチマークは1で作成されました。このベンチマークを実行するために使用したコードは次のとおりです。simple_benchmark
import iteration_utilities
import itertools
from itertools import zip_longest
def consume_all(it):
    return iteration_utilities.consume(it, None)
import simple_benchmark
b = simple_benchmark.BenchmarkBuilder()
@b.add_function()
def grouper(l, n):
    return consume_all(iteration_utilities.grouper(l, n))
def Craz_inner(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)
@b.add_function()
def Craz(iterable, n, fillvalue=None):
    return consume_all(Craz_inner(iterable, n, fillvalue))
def nosklo_inner(seq, size):
    return (seq[pos:pos + size] for pos in range(0, len(seq), size))
@b.add_function()
def nosklo(seq, size):
    return consume_all(nosklo_inner(seq, size))
def SLott_inner(ints, chunk_size):
    for i in range(0, len(ints), chunk_size):
        yield ints[i:i+chunk_size]
@b.add_function()
def SLott(ints, chunk_size):
    return consume_all(SLott_inner(ints, chunk_size))
def MarkusJarderot1_inner(iterable,size):
    it = iter(iterable)
    chunk = tuple(itertools.islice(it,size))
    while chunk:
        yield chunk
        chunk = tuple(itertools.islice(it,size))
@b.add_function()
def MarkusJarderot1(iterable,size):
    return consume_all(MarkusJarderot1_inner(iterable,size))
def MarkusJarderot2_inner(iterable,size,filler=None):
    it = itertools.chain(iterable,itertools.repeat(filler,size-1))
    chunk = tuple(itertools.islice(it,size))
    while len(chunk) == size:
        yield chunk
        chunk = tuple(itertools.islice(it,size))
@b.add_function()
def MarkusJarderot2(iterable,size):
    return consume_all(MarkusJarderot2_inner(iterable,size))
@b.add_arguments()
def argument_provider():
    for exp in range(2, 20):
        size = 2**exp
        yield size, simple_benchmark.MultiArgument([[0] * size, 10])
r = b.run()
1免責事項:私は、ライブラリの作者だiteration_utilitiesとsimple_benchmark。