2012-12-09 53 views
19

Hãy để data = [[3,7,2],[1,4,5],[9,8,7]]Tổng số danh sách các danh sách; trả về danh sách tổng hợp

Giả sử tôi muốn tổng hợp các phần tử cho chỉ mục của mỗi danh sách trong danh sách, như thêm số vào cột ma trận để có một danh sách. Tôi giả định rằng tất cả các danh sách trong dữ liệu đều bằng nhau về độ dài.

print foo(data) 

    [[3,7,2], 
    [1,4,5], 
    [9,8,7]] 
    _______ 
>>>[13,19,14] 

Làm cách nào tôi có thể lặp qua danh sách danh sách mà không nhận được chỉ mục ngoài phạm vi lỗi? Có lẽ lambda? Cảm ơn!

+0

[Bạn đã thử gì?] (Http://whathaveyoutried.com/) –

Trả lời

51

Bạn có thể thử này:

In [9]: l = [[3,7,2],[1,4,5],[9,8,7]] 

In [10]: [sum(i) for i in zip(*l)] 
Out[10]: [13, 19, 14] 

này sử dụng một sự kết hợp của zip* giản nén các file trong danh sách và sau đó nén các mục theo chỉ mục của họ. Sau đó, bạn sử dụng danh sách hiểu để lặp qua các nhóm chỉ mục tương tự, tổng hợp chúng và quay lại vị trí 'ban đầu' của chúng.

Để hy vọng làm cho nó rõ ràng hơn một chút, đây là những gì xảy ra khi bạn lặp qua zip(*l):

In [13]: for i in zip(*l): 
    ....:  print i 
    ....:  
    ....:  
(3, 1, 9) 
(7, 4, 8) 
(2, 5, 7) 

Trong trường hợp danh mục có chiều dài bất bình đẳng, bạn có thể sử dụng itertools.izip_longest với một fillvalue của 0 - điều này về cơ bản lấp đầy chỉ số mất tích với 0, cho phép bạn tổng hợp tất cả 'cột':

In [1]: import itertools 

In [2]: l = [[3,7,2],[1,4],[9,8,7,10]] 

In [3]: [sum(i) for i in itertools.izip_longest(*l, fillvalue=0)] 
Out[3]: [13, 19, 9, 10] 

Trong trường hợp này, đây là những gì iterating qua izip_longest sẽ trông như thế:

In [4]: for i in itertools.izip_longest(*l, fillvalue=0): 
    ...:  print i 
    ...:  
(3, 1, 9) 
(7, 4, 8) 
(2, 0, 7) 
(0, 0, 10) 
+0

Giải thích rất rõ ràng và mã súc tích. Cảm ơn!! – Albert

+0

@Albert Không sao cả, chúc may mắn với mọi thứ! – RocketDonkey

+2

Hoặc 'bản đồ (tổng, zip (* l))' (cái này là của tôi yêu thích). – arshajii

0

này phụ thuộc vào giả định của bạn rằng tất cả các danh sách trong (hoặc các hàng) có cùng độ dài, nhưng nó phải làm những gì bạn muốn:

sum_list = [] 

ncols = len(data[0]) 

for col in range(ncols): 
    sum_list.append(sum(row[col] for row in data)) 


sum_list 
Out[9]: [13, 19, 14] 
7

Đối với bất kỳ ma trận (hoặc số đầy tham vọng khác) hoạt động Tôi sẽ khuyên bạn nên nhìn vào NumPy.

Mẫu để giải quyết tổng của một mảng dọc theo trục thể hiện trong câu hỏi của bạn sẽ là:

>>> from numpy import array 
>>> data = array([[3,7,2], 
...  [1,4,5], 
...  [9,8,7]]) 
>>> from numpy import sum 
>>> sum(data, 0) 
array([13, 19, 14]) 

Dưới đây là tài liệu hướng dẫn NumPy cho chức năng tổng hợp của nó: http://docs.scipy.org/doc/numpy/reference/generated/numpy.sum.html#numpy.sum

Đặc biệt là số thứ hai là thú vị như nó cho phép dễ dàng xác định những gì cần được tóm tắt: tất cả các phần tử hoặc chỉ một trục cụ thể của một mảng n chiều có thể (như).

+0

Cảm ơn bạn đã hỏi. Tôi đã thêm một mẫu. Tôi nghĩ rằng đây sẽ là thời gian và không gian hiệu quả hơn bất kỳ mẫu nào khác. – Theuni

+0

Rất dễ dàng (và dễ dàng hơn cú pháp để tiêu hóa hơn của tôi :)). – RocketDonkey

+0

Được đánh giá cao - đặc biệt là vì tôi chưa bao giờ sử dụng Numpy trước đây, nhưng tôi biết một số người làm tính toán khoa học và sử dụng nó rộng rãi. Tôi đã rất ngạc nhiên khi thấy điều này dễ như thế nào. – Theuni

1
>>> data = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] 
>>> for column in enumerate(data[0]): 
...  count = sum([x[column[0]] for x in data]) 
...  print 'Column %s: %d' % (column[0], count) 
... 
Column 0: 3 
Column 1: 6 
Column 2: 9 
6

này sẽ cung cấp cho bạn số tiền cho mỗi sublist

data = [[3,7,2],[1,4],[9,8,7,10]] 
list(map(sum, data)) 
[12, 5, 34] 

Nếu bạn muốn tổng hợp trên tất cả các yếu tố và nhận được chỉ là một số tiền sau đó sử dụng này

data = [[3,7,2],[1,4],[9,8,7,10]] 
sum(sum(data, [])) 
51 
+0

Bạn không có ý định tham gia khóa học Đại số tuyến tính trên Coursera phải không? Bạn có thể giải thích lý do thứ hai hoạt động không? – Parseltongue

0
def sum(L): 
res = list() 
for j in range(0,len(L[0])): 
    tmp = 0 
    for i in range(0,len(L)): 
     tmp = tmp + L[i][j] 
    res.append(tmp) 
return res 
Các vấn đề liên quan