Không có được đơn giản hơn này, tôi nghĩ:
a=[("13.5",100)]
b=[("14.5",100), ("15.5", 100)]
c=[("15.5",100), ("16.5", 100)]
input=[a,b,c]
from collections import Counter
print sum(
(Counter(dict(x)) for x in input),
Counter())
Lưu ý rằng Counter
(còn được gọi là một MultiSet) là cấu trúc dữ liệu tự nhiên nhất cho dữ liệu của bạn (một loại bộ mà các yếu tố có thể thuộc nhiều hơn một lần, hoặc tương đương - một bản đồ với ngữ nghĩa Element -> OccurrenceCount. Bạn có thể đã sử dụng nó ở nơi đầu tiên, thay vì danh sách các bộ dữ liệu.
Cũng có thể:
from collections import Counter
from operator import add
print reduce(add, (Counter(dict(x)) for x in input))
Sử dụng reduce(add, seq)
thay vì sum(seq, initialValue)
nói chung là linh hoạt hơn và cho phép bạn bỏ qua đi qua các giá trị ban đầu không cần thiết.
Lưu ý rằng bạn cũng có thể sử dụng operator.and_
để tìm giao điểm của các số nhiều thay vì tổng.
Biến thể trên là chậm chạp, vì Bộ đếm mới được tạo trên mỗi bước. Hãy sửa lỗi đó.
Chúng tôi biết rằng Counter+Counter
trả lại Counter
mới bằng dữ liệu đã hợp nhất.Điều này là ổn, nhưng chúng tôi muốn tránh tạo thêm. Hãy sử dụng Counter.update
thay vì:
cập nhật (tự, iterable = None, ** kwds) phương pháp collections.Counter cởi
Giống như dict.update() nhưng thêm tội thay vì thay thế chúng. Nguồn có thể là một lần lặp lại, từ điển hoặc một phiên bản Bộ đếm khác.
Đó là những gì chúng tôi muốn. Hãy quấn nó với một chức năng tương thích với reduce
và xem những gì sẽ xảy ra.
def updateInPlace(a,b):
a.update(b)
return a
print reduce(updateInPlace, (Counter(dict(x)) for x in input))
Tốc độ này chỉ chậm hơn so với giải pháp của OP.
Benchmark: http://ideone.com/7IzSx(Cập nhật ngày với chưa một giải pháp, nhờ astynax)
(Ngoài ra: Nếu bạn rất muốn một one-liner, bạn có thể thay updateInPlace
bởi lambda x,y: x.update(y) or x
mà công trình cùng một cách và thậm chí chứng minh là một giây nhanh hơn, nhưng không thể đọc được. Đừng :-))
sử dụng 'Counter() ' –
@AshwiniChaudhary:' Counter() 'chỉ số lần xuất hiện, và khi các giá trị đã được điền trước, nó sẽ không hoạt động cho kịch bản này. –
@ChristianWitts xem giải pháp của tôi bên dưới. –