![](/img/trans.png)
[英]Sorting a list of list of tuples based on the sum of first field in the tuple in Python
[英]python sum tuple list based on tuple first value
假设我有以下列表元组:
myList = [(0,2),(1,3),(2,4),(0,5),(1,6)]
我想基于相同的第一个元组值对此列表求和:
[(n,m),(n,k),(m,l),(m,z)] = m*k + l*z
对于myList
sum = 2*5 + 3*6 = 28
我怎么能得到这个?
您可以使用collections.defaultdict
:
>>> from collections import defaultdict
>>> from operator import mul
>>> lis = [(0,2),(1,3),(2,4),(0,5),(1,6)]
>>> dic = defaultdict(list)
>>> for k,v in lis:
dic[k].append(v) #use the first item of the tuple as key and append second one to it
...
#now multiply only those lists which contain more than 1 item and finally sum them.
>>> sum(reduce(mul,v) for k,v in dic.items() if len(v)>1)
28
from operator import itemgetter
from itertools import groupby
def mul(args): # will work with more than 2 arguments, e.g. 2*3*4
return reduce(lambda acc, x: acc*x, args, 1)
myList = [(0,2),(1,3),(2,4),(0,5),(1,6)]
sorted_ = sorted(myList, key=itemgetter(0))
grouped = groupby(sorted_, key=itemgetter(0))
numbers = [[t[1] for t in items] for _, items in grouped]
muls = [mul(items) for items in numbers if len(items) > 1]
print sum(muls)
这个解决方案只需一次通过,而不是更易读的defaultdict
版本,它需要两次传递并可能占用更多空间:
myList = [(0,2),(1,3),(2,4),(0,5),(1,6)]
sum_ = 0
once, twice = {}, {}
for x, y in myList:
if x in once:
sum_ -= twice.get(x, 0)
twice[x] = twice.get(x, once[x]) * y
sum_ += twice[x]
else:
once[x] = y
>>> sum_
28
使用以下程序,即使您有多个条目,而不是只有两个相同的密钥,它将工作
#!/usr/local/bin/python3
myList = [(0,2),(1,3),(2,4),(0,5),(1,6),(1,2)]
h = {}
c = {}
sum = 0
for k in myList:
# if key value already present
if k[0] in c:
if k[0] in h:
sum = sum - h[k[0]]
h[k[0]] = h[k[0]] * k[1]
else:
h[k[0]] = c[k[0]] * k[1]
sum = sum + h[k[0]]
else:
# stores key and value if first time though the loop
c[k[0]] = k[1]
print('sum is' + str(sum))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.