2012-03-12 66 views
103

Tôi có danh sách python chạy vào danh sách 1000. Một cái gì đó như:Chia danh sách trăn thành "danh sách con" khác, ví dụ: danh sách nhỏ hơn

data=["I","am","a","python","programmer".....] 

nơi, len (dữ liệu) = nói 1003

bây giờ tôi muốn tạo ra một tập hợp con của danh sách này (dữ liệu) bằng cách phân chia danh sách ban đầu vào khối của 100. Vì vậy, tại cuối, Id muốn có một cái gì đó như:

data_chunk1=[.....] #first 100 items of list data 
data_chunk2=[.....] #second 100 items of list data 
. 
. 
. 
data_chunk11=[.....] # remainder of the entries,& its len <=100, len(data_chunk_11)=3 

Có cách nào để thực hiện nhiệm vụ này không? Rõ ràng là tôi có thể sử dụng dữ liệu [0: 100] và vân vân, nhưng tôi cho rằng điều đó cực kỳ không thiên về và rất kém hiệu quả.

Rất cám ơn.

+3

Bạn có thể sử dụng [chức năng array_split NumPy của ] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.array_split.html#numpy.array_split) ví dụ: 'np.array_split (np.array (dữ liệu), 20)' để chia thành 20 khối gần bằng nhau. Để chắc chắn rằng các khối có kích thước chính xác bằng 'np.split'. – AlexG

Trả lời

200

Tôi muốn nói

chunks = [data[x:x+100] for x in xrange(0, len(data), 100)] 

Nếu bạn đang sử dụng python 3.x range() thay thế python 2.x của xrange(), thay đổi mã ở trên để:

chunks = [data[x:x+100] for x in range(0, len(data), 100)] 
+3

Tôi muốn đi Bạn có thể có thể làm điều đó theo cách 'pythonic' nhiều hơn với itertools, nhưng nó sẽ xấu xí như tội lỗi! –

+6

Nếu bạn có một danh sách và muốn một danh sách, không có lý do gì để bận tâm với itertools. có ý nghĩa nếu bạn muốn chia nhỏ một luồng dữ liệu mà không bao giờ tạo ra toàn bộ điều. – alexis

+3

Sử dụng công cụ lặp đi lặp lại thực sự sẽ là cách ít nhiệt tình hơn để làm điều đó, phải không? – Pastafarian

6
chunks = [data[100*i:100*(i+1)] for i in range(len(data)/100 + 1)] 

Điều này tương đương với câu trả lời được chấp nhận. Ví dụ, rút ​​ngắn đến lô 10 để có thể đọc:

data = range(35) 
print [data[x:x+10] for x in xrange(0, len(data), 10)] 
print [data[10*i:10*(i+1)] for i in range(len(data)/10 + 1)] 

Đầu ra:

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34]] 
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34]] 
+2

Đó không phải là những gì được hỏi. –

+0

Trên thực tế nó là tương đương, ngoại trừ một lỗi mà lô cuối cùng là mất tích, bây giờ cố định. – qris

24

Thật sự tôi nghĩ rằng sử dụng lát đơn giản là giải pháp tốt nhất trong trường hợp này:

for i in range(0, len(data), 100): 
    chunk = data[i:i + 100] 
    ... 

Nếu bạn muốn tránh sao chép các lát, bạn có thể sử dụng itertools.islice(), nhưng dường như không cần thiết ở đây.

Các tài liệu itertools() cũng chứa nổi tiếng "mú" mẫu:

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

Bạn sẽ cần phải sửa đổi nó để điều trị những đoạn cuối cùng một cách chính xác, vì vậy tôi nghĩ rằng giải pháp thẳng về phía trước sử dụng lát đơn giản là một lợi thế.

+0

cảm ơn bạn đã trả lời. Tôi đã nghĩ về giải pháp lát đồng bằng đầu tiên của bạn, nhưng sau đó nghĩ rằng nó có thể là quá kém hiệu quả và quá ngây thơ của tôi .. Tôi hơi ngạc nhiên rằng không có một cách nhiệt tình (một lót) để đạt được nhiệm vụ này: ( – JohnJ

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