2009-08-02 42 views
8

Tôi đang tìm một hàm trăn sẵn (hoặc cơ chế) để phân đoạn danh sách thành các độ dài phân đoạn được yêu cầu (không có đột biến danh sách đầu vào). Dưới đây là đoạn code tôi đã có:Phân đoạn danh sách bằng 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ên quan http://stackoverflow.com/questions/1915170/split-a-generator -tiêu đề-mọi-n-mục-trong-pyt hon-splitevery – jfs

Trả lời

17

Bạn có thể sử dụng danh sách hiểu:

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

Bạn cũng có thể làm cho máy phát điện này, tức là (một [x: x + seg_length] cho x trong phạm vi (0, len (a), seg_length)) sẽ hiệu quả hơn cho các chuỗi lớn. – mhawke

+0

Mã một dòng này rất súc tích và hữu ích! –

2

không giống nhau ra, tôi vẫn nghĩ rằng grouper function là hữu ích:

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

cho python2 .4 và 2.5 không có izip_longest:

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

một số mã bản demo và đầu ra:

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

đầu ra: [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, Không có, Không) ]

4

Bạn cần sử dụng đầu ra như thế nào? Nếu bạn chỉ cần để lặp qua nó, bạn là tốt hơn hết tạo ra một iterable, một trong đó mang lại nhóm của bạn:

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 

Cách sử dụng Ví dụ:

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

này sử dụng ít bộ nhớ hơn là cố gắng xây dựng toàn bộ danh sách trong bộ nhớ cùng một lúc, nếu bạn chỉ Looping trên kết quả, bởi vì nó chỉ xây dựng một tập hợp con tại một thời điểm:

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

+1. Một cách tiếp cận rất hợp lý. Tôi sẽ ghi nhớ điều này nếu dữ liệu đầu vào của tôi tăng kích thước. – kjfletch

Các vấn đề liên quan