2010-03-17 5 views
9

eine Listeidiomatische Möglichkeit, Gruppen von n Elementen aus einer Liste in Python zu nehmen?

A = [1 2 3 4 5 6] 

Gibt es eine idiomatische (Pythonic) Art und Weise über sie gegeben laufen, als ob es

waren
B = [(1, 2) (3, 4) (5, 6)] 

andere als Indizierung? Das fühlt sich wie ein Überbleibsel aus C:

for a1,a2 in [ (A[i], A[i+1]) for i in range(0, len(A), 2) ]: 

ich kann nicht helfen, aber das Gefühl, es sollte mit itertools oder schneiden oder etwas einige cleveren Hack.

(Natürlich zwei zu einem Zeitpunkt ist nur ein Beispiel, ich eine Lösung möchte, die für jede n funktioniert.)

Edit: Verwandte Iterate over a string 2 (or n) characters at a time in Python aber auch die sauberste Lösung (angenommen, zip verwenden) doesn Verallgemeinern Sie gut zu höheren n ohne ein Listenverständnis und * -Notation.

+0

Ich denke, Ihre C Überbleibsel nicht so schlecht aussehen, aber ich würde schreiben 'A [i: i + 1]' statt 'A [i], A [ i + 1] '. Leichter auf beliebiges 'n' zu erweitern. –

+1

Duplizieren: Was ist der "pythonischste" Weg, um eine Liste in Chunks zu durchlaufen? http://stackoverflow.com/questions/434287/what-is-the-most-pythonic-way-to-iterate-over-a-list-in-chunks Siehe auch http://stackoverflow.com/questions/312443/how-do-you-Split-a-Liste-in-gleichmäßig-Größe-Chunks-in-Python http://StackOverflow.com/Questions/1335392/iteration-over-list-Slices http://StackOverflow.com/questions/760753/iterate-über-python-sequenz-in-multiple-of-n – jfs

+0

Die [referenzierte akzeptierte Antwort] (http://stackoverflow.com/a/1162636/923794) hat tatsächlich eine saubere, nein -Kopierlösung, und es besteht keine Notwendigkeit für ein Listenverständnis oder eine * -Notation. Am Ende sollten Sie die Daten irgendwo überschleifen, so dass jeder Loop/Comprehensions/Generator keinen zusätzlichen Preis hat. Kapsulieren Sie die referenzierte itertools.islice-basierte Lösung in eine Funktion, wenn Sie es kompakter mögen. – cfi

Antwort

11

Von http://docs.python.org/library/itertools.html:

from itertools import izip_longest 
def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 

i = grouper(3,range(100)) 
i.next() 
(0, 1, 2) 
+0

Dies kann nicht subjektiv idiomatisch sein oder Listenkompressen und Notation vermeiden, aber es ist "pythonisch" genug, um in der Dokumentation zu sein. – MattH

+0

Ah, ich wusste, dass es irgendwo existiert. Vielen Dank! – Wang

Verwandte Themen