2009-08-02 13 views
8

Je cherche une fonction (ou un mécanisme) intégré python pour segmenter une liste en longueurs de segment requises (sans muter la liste d'entrée). Voici le code que je l'ai déjà:Segmenter une liste en Python

>>> 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

liés http://stackoverflow.com/questions/1915170/split-a-generator -abordable-tous-n-articles-en-pyt hon-splitevery – jfs

Répondre

17

Vous pouvez utiliser la compréhension de la liste:

>>> 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

Vous pouvez également en faire un générateur, c'est-à-dire (a [x: x + seg_length] pour x dans la plage (0, len (a), seg_length)) qui sera plus efficace pour les grandes séquences. – mhawke

+0

Ce code de ligne est si concis et utile! –

2

pas la même sortie, je pense toujours que le grouper function est utile:

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

pour python2 .4 et 2,5 qui n'ont pas izip_longest:

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

un code de démonstration et de sortie:

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

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

4

Comment devez-vous utiliser la sortie? Si vous ne devez itérer, vous êtes mieux de créer un itératives, qui donne à vos groupes:

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 

Exemple d'utilisation:

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

Cela utilise beaucoup moins de mémoire que d'essayer de construire la liste entière en mémoire à la fois, si vous Looping que sur le résultat, parce qu'il construit qu'un sous-ensemble à la fois:

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

+1. Une approche très sensée. Je garderai cela à l'esprit si mes données d'entrée augmentent en taille. – kjfletch

Questions connexes