Sum numbers by letter in list of tuples

家住魔仙堡 提交于 2019-12-17 20:27:29

问题


I have a list of tuples:

[ ('A',100), ('B',50), ('A',50), ('B',20), ('C',10) ]

I am trying to sum up all numbers that have the same letter. I.e. I want to output

[('A', 150), ('B', 70), ('C',10)] 

I have tried using set to get the unique values but then when I try and compare the first elements to the set I get

TypeError: unsupported operand type(s) for +: 'int' and 'str'

Any quick solutions to match the numbers by letter?


回答1:


Here is a one(and a half?)-liner: group by letter (for which you need to sort before), then take the sum of the second entries of your tuples.

from itertools import groupby
from operator import itemgetter

data = [('A', 100), ('B', 50), ('A', 50), ('B', 20), ('C', 10)]
res = [(k, sum(map(itemgetter(1), g)))
       for k, g in groupby(sorted(data, key=itemgetter(0)), key=itemgetter(0))]
print(res)
// => [('A', 150), ('B', 70), ('C', 10)]

The above is O(n log n) — sorting is the most expensive operation. If your input list is truly large, you might be better served by the following O(n) approach:

from collections import defaultdict

data = [('A', 100), ('B', 50), ('A', 50), ('B', 20), ('C', 10)]

d = defaultdict(int)
for letter, value in data:
    d[letter] += value
res = list(d.items())
print(res)
// => [('B', 70), ('C', 10), ('A', 150)]



回答2:


How about this: (assuming a is the name of the tuple you have provided)

letters_to_numbers = {}
for i in a:
    if i[0] in letters_to_numbers:
        letters_to_numbers[i[0]] += i[1]
    else:
        letters_to_numbers[i[0]] = i[1]
b = letters_to_numbers.items()

The elements of the resulting tuple b will be in no particular order.




回答3:


In order to achieve this, firstly create a dictionary to store your values. Then convert the dict object to tuple list using .items() Below is the sample code on how to achieve this:

my_list = [ ('A',100), ('B',50), ('A',50), ('B',20), ('C',10) ]
my_dict = {}
for key, val in my_list:
    if key in my_dict:
        my_dict[key] += val
    else:
        my_dict[key] = val

my_dict.items()
# Output: [('A', 150), ('C', 10), ('B', 70)]



回答4:


What is generating the list of tuples? Is it you? If so, why not try a defaultdict(list) to append the values to the right letter at the time of making the list of tuples. Then you can simply sum them. See example below.

>>> from collections import defaultdict
>>> val_store = defaultdict(list)
>>> # next lines are me simulating the creation of the tuple
>>> val_store['A'].append(10)
>>> val_store['B'].append(20)
>>> val_store['C'].append(30)
>>> val_store
defaultdict(<class 'list'>, {'C': [30], 'A': [10], 'B': [20]})
>>> val_store['A'].append(10)
>>> val_store['C'].append(30)
>>> val_store['B'].append(20)
>>> val_store
defaultdict(<class 'list'>, {'C': [30, 30], 'A': [10, 10], 'B': [20, 20]})

>>> for val in val_store:
...   print(val, sum(val_store[val]))
... 
C 60
A 20
B 40



回答5:


>>> from collections import Counter
>>> c = Counter()
>>> for k, num in items:
        c[k] += num


>>> c.items()
[('A', 150), ('C', 10), ('B', 70)]

Less efficient (but nicer looking) one liner version:

>>> Counter(k for k, num in items for i in range(num)).items()
[('A', 150), ('C', 10), ('B', 70)]



回答6:


Try this:

a = [('A',100), ('B',50), ('A',50), ('B',20), ('C',10) ]

letters = set([s[0] for s in a])

new_a = []
for l in letters:
    nums = [s[1] for s in a if s[0] == l]
    new_a.append((l, sum(nums)))

print new_a    

Results:

[('A', 150), ('C', 10), ('B', 70)]



回答7:


A simpler approach

x = [('A',100),('B',50),('A',50),('B',20),('C',10)]
y = {}
for _tuple in x:
    if _tuple[0] in y:
        y[_tuple[0]] += _tuple[1]
    else:
        y[_tuple[0]] = _tuple[1]
print [(k,v) for k,v in y.iteritems()]



回答8:


A one liner:

>>> x = [ ('A',100), ('B',50), ('A',50), ('B',20), ('C',10) ]
>>> {
...     k: reduce(lambda u, v: u + v, [y[1] for y in x if y[0] == k])
...     for k in [y[0] for y in x]
...     }.items()
[('A', 150), ('C', 10), ('B', 70)]


来源:https://stackoverflow.com/questions/39734549/sum-numbers-by-letter-in-list-of-tuples

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!