2009-08-02 12 views
8

Ich suche nach einer eingebauten Python-Funktion (oder Mechanismus), um eine Liste in erforderliche Segmentlängen zu segmentieren (ohne die Eingabeliste zu mutieren). Hier ist der Code habe ich bereits:Eine Liste in Python segmentieren

>>> def split_list(list, seg_length): 
...  inlist = list[:] 
...  outlist = [] 
...  
...  while inlist: 
...   outlist.append(inlist[0:seg_length]) 
...   inlist[0:seg_length] = [] 
...  
...  return outlist 
... 
>>> alist = range(10) 
>>> split_list(alist, 3) 
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] 
+0

Zusammenhang http://stackoverflow.com/questions/1915170/split-a-generator -iterable-alle-n-Artikel-in-pyt hon-splitevery – jfs

Antwort

17

Sie Liste Verständnis verwenden können:

>>> seg_length = 3 
>>> a = range(10) 
>>> [a[x:x+seg_length] for x in range(0,len(a),seg_length)] 
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] 
+4

Sie können dies auch zu einem Generator machen, d. h. (a [x: x + seg_length] für x im Bereich (0, len (a), seg_length)), was für große Sequenzen effizienter ist. – mhawke

+0

Dieser Code ist so kurz und nützlich! –

2

nicht die gleiche Leistung, ich denke immer noch die grouper function ist hilfreich:

from itertools import izip_longest 
def grouper(iterable, n, fillvalue=None): 
    args = [iter(iterable)] * n 
    return izip_longest(*args, fillvalue=fillvalue) 

für Python2 .4 und 2.5 ohne izip_longest:

from itertools import izip, chain, repeat 
def grouper(iterable, n, padvalue=None): 
    return izip(*[chain(iterable, repeat(padvalue, n-1))]*n) 

einig Demo-Code und Ausgabe:

alist = range(10) 
print list(grouper(alist, 3)) 

output: [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, None, None) ]

4

Wie müssen Sie den Ausgang verwenden? Wenn Sie nur über sie zu durchlaufen müssen, sind Sie besser dran, eine iterable, eine zu schaffen, die Ihre Gruppen ergeben:

def split_by(sequence, length): 
    iterable = iter(sequence) 
    def yield_length(): 
     for i in xrange(length): 
      yield iterable.next() 
    while True: 
     res = list(yield_length()) 
     if not res: 
      return 
     yield res 

Anwendungsbeispiel:

>>> alist = range(10) 
>>> list(split_by(alist, 3)) 
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]] 

Dieser weit weniger Speicher verwendet als zu versuchen, das zu konstruieren ganz Liste auf einmal im Speicher, wenn Sie über das Ergebnis sind Looping, weil es nur eine Teilmenge zu einer Zeit errichtet:

>>> for subset in split_by(alist, 3): 
...  print subset 
... 
[0, 1, 2] 
[3, 4, 5] 
[6, 7, 8] 
[9] 
+0

+1. Ein sehr vernünftiger Ansatz. Ich werde dies berücksichtigen, wenn meine Eingabedaten an Größe zunehmen. – kjfletch