Charlie
Charlie

Reputation: 63

How can i compare strings in a tuple that is inside a list

I have this list of tuples [(amount, name)]:

[(214.05, 'Charlie'), (153.57, 'Ben'),(213.88, 'Charlie')]

I am trying to compare them by their names and if there is a tuple that has the same name, I want to add the amounts together.

The output would go into another list with the same structure [(amount,name)].

I managed to extract the name part with this:

for i in range(0, len(spendList)):
    print(spendList[i][1])

The output:

Charlie
Ben
Charlie

How can I compare the names with each other?

Upvotes: 3

Views: 2413

Answers (4)

RoadRunner
RoadRunner

Reputation: 26315

You can group the amounts per name with a collections.defaultdict, then sum the amounts at the end:

from collections import defaultdict

data = [(214.05, 'Charlie'), (153.57, 'Ben'),(213.88, 'Charlie')]

d = defaultdict(list)
for amount, name in data:
    d[name].append(amount)

print([(_, sum(v)) for _, v in d.items()])
# [('Charlie', 427.93), ('Ben', 153.57)]

Upvotes: 2

Stephen Rauch
Stephen Rauch

Reputation: 49804

One way to do these sorts of operations is to use dict.setdefault() like:

Code:

data = [(214.05, 'Charlie'), (153.57, 'Ben'), (213.88, 'Charlie')]
summed = {}
for amount, name in data:
    summed.setdefault(name, []).append(amount)
summed = [(sum(amounts), name) for name, amounts in summed.items()]
print(summed)

How does this work?

  1. Start by defining a dict object to accumulate the amounts for each name.

     summed = {}
    
  2. Step through every pair of amounts and names:

     for amount, name in data:
    
  3. Using the dict property that things that hash the same will end up in the same slot in dict, and the dict method: setdefault() to make sure that the dict has an empty list available for every name we come across, create a list of amounts for each name:

     summed.setdefault(name, []).append(amount)
    

    This creates a dict of lists like:

     {'Charlie': [214.05, 213.88], 'Ben': [153.57]}
    
  4. Finally using a comprehension we can sum() up all of the items with the same name.

     summed = [(sum(amounts), name) for name, amounts in summed.items()]
    

Results:

[(427.93, 'Charlie'), (153.57, 'Ben')]

Upvotes: 3

Jan
Jan

Reputation: 43169

First sort your list, then use itertools.groupby with a small lambda function:

from itertools import groupby

lst = [(214.05, 'Charlie'), (153.57, 'Ben'),(213.88, 'Charlie')]
lst = sorted(lst, key=lambda x: x[1])

for k,v in groupby(lst, key = lambda x: x[1]):
    amount = sum(x[0] for x in v)
    print("Name: {}, Amount: {}".format(k, amount))

Which yields

Name: Ben, Amount: 153.57
Name: Charlie, Amount: 427.93

Or, even shorter with a dict comprehension:

summary = {name: amount 
            for name, v in groupby(lst, key = lambda x: x[1])
            for amount in [sum(x[0] for x in v)]}

print(summary)
# {'Charlie': 427.93, 'Ben': 153.57}

Upvotes: 2

Veera Balla Deva
Veera Balla Deva

Reputation: 788

text = [(214.05, 'Charlie'), (153.57, 'Ben'),(213.88, 'Charlie')]
dictionary = {}
for val in text:
    amount, name = val
    if name in dictionary:
        dictionary[name] += amount
    else:
        dictionary[name] = amount
print(*dictionary.items(),sep="\n")
>>('Charlie', 427.93)
  ('Ben', 153.57)

Upvotes: 3

Related Questions