San9096
San9096

Reputation: 251

Summing elements in list of lists in Python

I have the following kind of list:

myList = [[500, 5], [500, 10], [500, 3], [504, 9], [505, 10], [505, 20]]

I don't want to have values with the same first element, so i wanted to do this: if two or more elements have the same first value, sum all the second values of the element with the same first value and remove the duplicates, so in my example the new output would be:

myList = [[500, 18], [504, 9], [505, 30]]

How can i do this? I was thinking of using Lambda functions but i don't know how to create the function; other solutions i'm thinking about require a massive amount of for loops, so i was thinking if there is an easier way to do this. Any kind of help is appreciated!

Upvotes: 1

Views: 360

Answers (5)

sammywemmy
sammywemmy

Reputation: 28729

You can use itertools groupby to group the sublists by the first item in the sublist, sum the last entries in the sublist, and create a new list of group keys, with the sums :

from itertools import groupby

from operator import itemgetter

 #sort data
 #unnecessary IMO, since data looks sorted
 #it is however, required to sort data
 #before running the groupby function

 myList = sorted(myList, key = itemgetter(0))

Our grouper will be the first item in each sublist (500, 504, 505)

 #iterate through the groups
 #sum the ends of each group
 #pair the sum with the grouper
 #return a new list

result = [[key, sum(last for first, last in grp)] 
           for key, grp 
           in groupby(myList, itemgetter(0))]

print(result)

[[500, 18], [504, 9], [505, 30]]

Upvotes: 1

Jan Christoph Terasa
Jan Christoph Terasa

Reputation: 5945

Use a defaultdict:

import collections

# by default, non-existing keys will be initialized to zero
myDict = collections.defaultdict(int)

for key, value in myList:
    myDict[key] += value

# transform back to list of lists
myResult = sorted(list(kv) for kv in myDict.items())

Upvotes: 5

PApostol
PApostol

Reputation: 2302

myList = [[500, 5], [500, 10], [500, 3], [504, 9], [505, 10], [505, 20]]

temp = {}

for first, second in myList:
  if first in temp:
    temp[first] += second
  else:
    temp[first] = second

result = [[k, v] for k, v in temp.items()]
print(result)

Upvotes: -1

Itamar Mushkin
Itamar Mushkin

Reputation: 2905

using the pandas library:

[[k, v] for k, v in pd.DataFrame(myList).groupby(0).sum()[1].items()]

Breaking it down:

  • pd.DataFrame(myList) creates a DataFrame where each row is one of the short lists in myList:

        0   1
    0   500 5
    1   500 10
    2   500 3
    3   504 9
    4   505 10
    5   505 20
    
  • (...).groupby(0)[1].sum() groups by the first column, takes the values from the second one (to create a series instead of a dataframe) and sums them

  • [[k,v] for k, v in (...).items()] is simple list comprehension (treating the series as a dictionary), to output it back as a list like you wanted.

Output:

[[500, 18], [504, 9], [505, 30]]

The list comprehension can be made even shorter by casting each of the .items() to a list:

list(map(list, pd.DataFrame(myList).groupby(0)[1].sum().items()))

Upvotes: 3

Jean-Marc Volle
Jean-Marc Volle

Reputation: 3333

An easier to read implementation (less pythonesqe though :-) )

myList = [[500, 5], [500, 10], [500, 3], [504, 9], [505, 10], [505, 20]]


sums = dict()
for a,b in myList:
    if a in sums:
        sums[a] += b
    else:
        sums[a] = b

res = []
for key,val in sums.items():
    res.append([key,val])

print (sorted(res))

Upvotes: 1

Related Questions