2009-08-02 11 views
8

Bir listeyi istenen segment uzunluklarına (giriş listesini değiştirmeden) bölümlendirmek için bir python dahili işlevi (veya mekanizması) arıyorum.Python'da bir listeyi ayırma

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

http://stackoverflow.com/questions/1915170/split-a-generator: bu sadece bir defada bir alt kümesini oluşturur çünkü sadece, sonuç üzerinde döngü halinde bellekte aynı anda tüm liste, -iterable-her-n-ürün-içinde-PYT hon-splitevery – jfs

cevap

17

Sen liste anlama kullanabilirsiniz: Python2 için

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

:

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

Ayrıca, bu büyük bir dizi için daha verimli olacak şekilde bir jeneratör, yani (x için bir [x: x + seg_length] x aralığında (0, len (a), seg_length)) yapabilirsiniz. – mhawke

+0

Bu bir satır kodu çok özlü ve yararlı! –

2

değil, hala grouper function yararlıdır aynı çıkışı düşünüyorum İşte zaten kodudur .4 ve 2.5, izip_longest'e sahip değildir:

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

bir demo kodu ve çıkış:

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

çıkışı: [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, Yok, yok) ]

4

Çıkışı nasıl kullanmanız gerekiyor?

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 

Kullanım örneği: Bu inşa etmeye çalışırken daha az bellek kullanıyor

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

sadece üzerinde yineleme gerekiyorsa, size gruplarını veren bir iterable, bir tane oluşturmak daha iyi olur ilgili

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

+1. Çok mantıklı bir yaklaşım. Giriş verilerimin boyutu büyüdüğünde bunu aklımda tutacağım. – kjfletch