SalazarSid
SalazarSid

Reputation: 64

Python : Adding the same elements of a list iteratively

I have a list of elements as given below-

[(a,1),(b,2),(c,3),(d,4),(e,5),(f,6),(a,7),(b,8),(c,9),(d,10),(e,11),(f,12)]

I am trying to add the value given next to a letter with a different value given next to the same letter.

For example- "a" has a value of 1, the program should compare "a" to all the terms in the list until it finds a match. Once it finds another term "a" having a value of 7, it should add the two values so that we get a=8.

Expected output is-

a=8, b=10, c=12, d=14, e=16, f=18

Upvotes: 0

Views: 79

Answers (4)

vash_the_stampede
vash_the_stampede

Reputation: 4606

Using itertools.groupby and operator.itemgetter, can be substituted with lambda

from itertools import groupby
from operator import itemgetter

lst = sorted(lst, key=itemgetter(0))
d = {k: sum(i[1] for i in g) for k, g in groupby(lst, key=itemgetter(0))}
# {'a': 8, 'b': 10, 'c': 12, 'd': 14, 'e': 16, 'f': 18}

Dictionary comprehension expanded:

d = {}
for k, g in groupby(lst, key=itemgetter(0)):
    d[k] = sum(i[1] for i in g)

Upvotes: 1

DeepSpace
DeepSpace

Reputation: 81594

The solution you suggest is going to have a complexity of O(n2).

You can do it in O(n) by using defaultdict (since it requires a single pass over the entire list):

from collections import defaultdict

li = [('a', 1), ('b', 2), ('c', 3), ('d', 4), ('e', 5), ('f', 6), ('a', 7), ('b', 8), 
      ('c', 9), ('d', 10), ('e', 11), ('f', 12)]

output = defaultdict(int)

for letter, number in li:
    output[letter] += number

print(output)
# defaultdict(<class 'int'>, {'a': 8, 'b': 10, 'c': 12, 'd': 14, 'e': 16, 'f': 18})

This solution of course requires the elements to be hashable, but this can be remedied by using the string representation of the elements if they are not.

Upvotes: 5

Daniel Hepper
Daniel Hepper

Reputation: 29977

from collections import defaultdict

l = [('a',1),('b',2),('c',3),('d',4),('e',5),('f',6),('a',7),('b',8),('c',9),('d',10),('e',11),('f',12)]

d = defaultdict(int)
for k, v in l:
    d[k] += v

Result:

defaultdict(<class 'int'>, {'a': 8, 'b': 10, 'c': 12, 'd': 14, 'e': 16, 'f': 18})

Upvotes: 0

Melih Taşdizen
Melih Taşdizen

Reputation: 81

An answer that doesn't utilize the defaultdict.

_list = [("a",1),("b",2),("c",3),("d",4),("e",5),("f",6),("a",7),("b",8),("c",9),("d",10),("e",11),("f",12)]

tmp = dict()

for k in _list:
    try:
        tmp[k[0]] += k[1]
    except KeyError:
        tmp[k[0]] = k[1]

print(tmp)    

Result:

{'a': 8, 'b': 10, 'c': 12, 'd': 14, 'e': 16, 'f': 18}

Upvotes: 1

Related Questions