Суммировать каждое значение в списке кортежей
У меня есть список кортежей, подобных этому:
l = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 0)]
Я хочу создать простой однострочный слой, который даст мне следующий результат:
r = (25, 20) or r = [25, 20] # don't care if tuple or list.
Это будет выглядеть следующим образом:
r = [0, 0]
for t in l:
r[0]+=t[0]
r[1]+=t[1]
Я уверен, что это очень просто, но я не могу думать об этом.
Примечание. Я уже рассмотрел похожие вопросы:
Как суммировать первое значение в наборе списков в кортеже?
Как суммировать первое значение в каждом кортеже в списке кортежей в Python?
Ответы
Ответ 1
Используйте zip()
и sum()
:
In [1]: l = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 0)]
In [2]: [sum(x) for x in zip(*l)]
Out[2]: [25, 20]
или
In [4]: map(sum, zip(*l))
Out[4]: [25, 20]
timeit
результаты:
In [16]: l = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 0)]*1000
In [17]: %timeit [sum(x) for x in zip(*l)]
1000 loops, best of 3: 1.46 ms per loop
In [18]: %timeit [sum(x) for x in izip(*l)] #prefer itertools.izip
1000 loops, best of 3: 1.28 ms per loop
In [19]: %timeit map(sum, zip(*l))
100 loops, best of 3: 1.48 ms per loop
In [20]: %timeit map(sum, izip(*l)) #prefer itertools.izip
1000 loops, best of 3: 1.29 ms per loop
Ответ 2
Я хочу добавить что-то к данному ответу:
Если у меня есть массив dict, например.
l = [{'quantity': 10, 'price': 5},{'quantity': 6, 'price': 15},{'quantity': 2, 'price': 3},{'quantity': 100, 'price': 2}]
и я хочу получить две (или более) суммы расчетной величины над значениями, например. сумма величин и цены * количество
Я могу сделать:
(total_quantity, total_price) = (
sum(x) for x in zip(*((item['quantity'],
item['price'] * item['quantity'])
for item in l)))
Вместо:
total_quantity = 0
total_price = 0
for item in l:
total_quantity += item['quantity']
total_price += item['price'] * item['quantity']
Может быть, первое решение менее читаемо, но более "pythonesque":)
Ответ 3
Без использования zip
sum(e[0] for e in l), sum(e[1] for e in l)