Wie teilt man eine Liste in gleich große Teile auf?

Ich habe eine Liste beliebiger Länge, und ich muss sie in gleich große Teile aufteilen und darauf operieren. Es gibt einige offensichtliche Möglichkeiten, dies zu tun, wie die Führung eines Zählers und zwei Listen, und wenn die zweite Liste füllt, fügen Sie es der ersten Liste und leeren Sie die zweite Liste für die nächste Runde von Daten, aber dies ist potenziell extrem teuer.

Ich habe mich gefragt, ob jemand eine gute Lösung für Listen beliebiger Länge hat, z.B. mit Generatoren.

Ich habe in itertools nach etwas Nützlichem gesucht, aber ich konnte nichts offensichtlich Nützliches finden. Vielleicht habe ich es aber auch übersehen.

Verwandte Frage: Was ist der "pythonischste" Weg, um über eine Liste in Abschnitten zu iterieren?

Lösung

Hier ist ein Generator, der die gewünschten Chunks liefert:

def chunks(l, n):
    """Yield successive n-sized chunks from l."""
    for i in range(0, len(l), n):
        yield l[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]]

Wenn Sie Python 2 verwenden, sollten Sie xrange() anstelle von range() verwenden:

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

Sie können auch einfach das Listenverständnis verwenden, anstatt eine Funktion zu schreiben, obwohl es eine gute Idee ist, Operationen wie diese in benannten Funktionen zu kapseln, damit Ihr Code leichter zu verstehen ist. Python 3:

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

Python 2 Version:

[l[i:i + n] for i in xrange(0, len(l), n)]
Kommentare (10)

Hier ist ein Generator, der mit beliebigen Iterablen arbeitet:

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

Beispiel:

>>> 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]]
Kommentare (0)

Wenn Sie die Listengröße kennen:

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

Wenn Sie es nicht wissen (ein Iterator):

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

Im letzteren Fall kann man es schöner formulieren, wenn man sicher sein kann, dass die Folge immer eine ganze Anzahl von Teilen der gegebenen Größe enthält (d. h. es gibt kein unvollständiges letztes Teilstück).

Kommentare (1)