简体   繁体   中英

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!

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())

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()))

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))

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]]
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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM