2016-11-09 30 views
9

Với 3 vectơ lồng nhau:Khái quát thêm danh sách lồng nhau

>>> a 
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
>>> b 
[[10, 20, 30], [40, 50, 60], [70, 80, 90]] 
>>> c 
[[100, 200, 300], [400, 500, 600], [700, 800, 900]] 

tôi có thể thêm các vectơ cùng với một bản đồ/tổng/hiểu zip như vậy:

>>> [map(sum,zip(i,j,k)) for i,j,k in zip(a,b,c)] 
[[111, 222, 333], [444, 555, 666], [777, 888, 999]] 

Tôi đã tự mở rộng này từ thêm hai danh sách lại với nhau, nhưng có cách nào để khái quát hóa điều này để xử lý một số danh sách tùy ý không?

(Python 2.7 mà không sử dụng thư viện bên ngoài ưa thích)

+1

Nếu bạn không có thư viện bên ngoài? 'itertools' có thể là một nhập khẩu hữu ích –

+0

Ngoài ra - nó có thể được khái quát hóa thành các mức lồng nhau tùy ý không? (không phải vấn đề thực tế của tôi nhưng chỉ xảy ra với tôi là có liên quan) – paulw1128

+0

@ cricket_007 Cảm ơn - đó là những gì tôi có ý nghĩa. Tôi sẽ chỉnh sửa câu hỏi. – paulw1128

Trả lời

4

Đây là một cách tiếp cận chung:

from itertools import izip 
def multiple_sum(*args): 
    return [map(sum, izip(*items)) for items in izip(*args)] 

Demo:

In [13]: multiple_sum(a, b, c) 
Out[13]: [[111, 222, 333], [444, 555, 666], [777, 888, 999]] 

Lưu ý rằng vì trong Python 2.7 zip trả về một danh sách, nên sử dụng nó khi bạn chỉ muốn lặp qua các kết quả, và thay vào đó hãy sử dụng itertools.izip trả về một trình lặp.

Đây là một cách khác để sử dụng itertools.starmap() đó là nhanh hơn so với phương pháp previouse:

def multiple_sum(*args): 
    return [map(sum, lst) for lst in starmap(zip, zip(*args))] 

Benchmark:

In [32]: %timeit [map(sum, izip(*items)) for items in izip(a, b, c)] 
100000 loops, best of 3: 3.93 µs per loop 

In [33]: %timeit [map(sum, lst) for lst in starmap(zip, zip(a, b , c))] 
100000 loops, best of 3: 3.01 µs per loop 
3

này nên làm việc:

lists = [a,b,c] 
[map(sum,zip(*zipped_lists)) for zipped_lists in zip(*lists)] 
3

Nếu bạn có một danh sách liệt kê ([a,b,c]), bạn có thể làm như sau :

>>> lists = [a,b,c] 
>>> [map(sum, zip(*l)) for l in zip(*lists)] 
[[111, 222, 333], [444, 555, 666], [777, 888, 999]] 
Các vấn đề liên quan