Python将元组的第二个元素与第一个元素求和

Python将元组的第二个元素与第一个元素求和,python,list,Python,List,我在Python3中有以下两个列表: list1 = [(3, 2), (1, 5), (4, 2), (2, 0)] list2 = [(1, 6), (2, 1), (3, 3), (4, 0)] 列表中的每个元组的形式为(id,score)。我想分别合并每个id的两个列表中的分数,然后按分数降序排序。因此,输出应为: list3 = [(1, 11), (3, 5), (4, 2), (2, 1)] 最简单的方法是什么?使用groupby按id分组,找到他们的分数总和,并按分数降序排序

我在Python3中有以下两个列表:

list1 = [(3, 2), (1, 5), (4, 2), (2, 0)]
list2 = [(1, 6), (2, 1), (3, 3), (4, 0)]
列表中的每个元组的形式为(id,score)。我想分别合并每个id的两个列表中的分数,然后按分数降序排序。因此,输出应为:

list3 = [(1, 11), (3, 5), (4, 2), (2, 1)]

最简单的方法是什么?

使用
groupby
按id分组,找到他们的分数总和,并按分数降序排序:

from itertools import groupby

list1 = [(3, 2), (1, 5), (4, 2), (2, 0)]
list2 = [(1, 6), (2, 1), (3, 3), (4, 0)]

f = lambda x: x[0]
list3 = sorted([(k, sum(x[1] for x in g)) for k, g in groupby(sorted(list1 + list2, key=f), key=f)], key=lambda x: x[1], reverse=True)

# [(1, 11), (3, 5), (4, 2), (2, 1)]

没有任何外部依赖性的更简单解决方案可能是:

list1 = [(3, 2), (1, 5), (4, 2), (2, 0)]
list2 = [(1, 6), (2, 1), (3, 3), (4, 0)]

list1.sort()
list2.sort()

list3 = [(list1[i][0], list1[i][1] + list2[i][1]) for i in range(len(list1))]
list3.sort(key=lambda x: x[1], reverse=True)

print(list3)

#[(1, 11), (3, 5), (4, 2), (2, 1)]

尽管这假设了一些事情:

  • 您没有重复的ID
  • 您总是在
    [0]
    索引中有ID,在
    [1]
  • 您的两个列表总是相同的形状
  • 您只有两个列表
  • 您没有缺少的ID(即列表1中的ID为1-4,列表2中的ID为2-5)
也许这对这个案子没问题?取决于范围有多广
适用于您希望的情况。

一种方法是将至少一个列表转换为字典:

d = dict(list2)
print(sorted(((k, v+d[k]) for k, v in list1), 
             key=lambda a: a[1], reverse=True))
对于可能有2个以上列表且并非每个id都必须出现在每个列表中的更一般情况,这可能会变成:

dicts = [dict(L) for L in [list1, list2]]
keys = set().union(*dicts)   # get all of the IDs
sums = ((k, sum(d.get(k, 0) for d in dicts)) for k in keys)
print(sorted(sums, key=lambda a: a[1], reverse=True))
或者更容易理解

sums = {}
for scores in [list1, list2]:
    for id_, score in scores:`
        if id_ in sums:
            sums[id_] += score
        else:
            sums[id_] = score
 print(sorted(sums, key=lambda a: a[1], reverse=True))
也许最好的选择是使用
计数器
,它有一个
最常用的
方法来进行您想要的排序

from collections import Counter
print((Counter(dict(list1)) + Counter(dict(list2))).most_common())
另一个使用dict理解的解决方案:


试着用字典代替列表。从id中提取分数会有很大帮助。您需要按[1],而不是[0]排序:
[(1,11)、(3,5)、(4,2)、(2,1)]
@WhereisourMonica,抱歉!这不是
groupby
的工作方式。排序与列表的最终排序无关。
sorted({id: dict(list1).get(id, 0) + dict(list2).get(id, 0) for id in dict(list1)}.items(), reverse=True, key=lambda x: x[1])
[(1, 11), (3, 5), (4, 2), (2, 1)]