假设我有以下两个元组列表
myList = [(1, 7), (3, 3), (5, 9)]
otherList = [(2, 4), (3, 5), (5, 2), (7, 8)]
returns => [(1, 7), (2, 4), (3, 8), (5, 11), (7, 8)]
我想设计一个合并操作,通过检查元组的第一个元素上的任何交集来合并这两个列表,如果有交叉点,则添加每个元组的第二个元素(合并两个)。在操作之后,我想根据第一个元素进行排序。
我也发布了这个,因为我认为它是一个非常普遍的问题,有一个明显的解决方案,但我觉得这个问题可能有非常pythonic的解决方案;)
答案 0 :(得分:14)
使用字典作为结果:
result = {}
for k, v in my_list + other_list:
result[k] = result.get(k, 0) + v
如果您想要一个元组列表,可以通过result.items()
获取。结果列表将按任意顺序排列,但当然您可以根据需要对其进行排序。
(请注意,我重命名了您的列表以符合Python的样式约定。)
答案 1 :(得分:4)
使用defaultdict:
from collections import defaultdict
results_dict = defaultdict(int)
results_dict.update(my_list)
for a, b in other_list:
results_dict[a] += b
results = sorted(results_dict.items())
注意:排序序列时,sorted
按序列中的第一项排序。如果第一个元素相同,则它比较第二个元素。您可以使用sorted
关键字参数为key
一个函数排序:
results = sorted(results_dict.items(), key=lambda x: x[1]) #sort by the 2nd item
或
results = sorted(results_dict.items(), key=lambda x: abs(x[0])) #sort by absolute value
答案 2 :(得分:1)
使用itertools的方法:
>>> myList = [(1, 7), (3, 3), (5, 9)]
>>> otherList = [(2, 4), (3, 5), (5, 2), (7, 8)]
>>> import itertools
>>> merged = []
>>> for k, g in itertools.groupby(sorted(myList + otherList), lambda e: e[0]):
... merged.append((k, sum(e[1] for e in g)))
...
>>> merged
[(1, 7), (2, 4), (3, 8), (5, 11), (7, 8)]
首先将两个列表连接在一起并对其进行排序。 itertools.groupby返回合并列表的元素,按元组的第一个元素分组,因此它只是将它们相加并将其放入合并列表中。
答案 3 :(得分:0)
>>> [(k, sum(v for x,v in myList + otherList if k == x)) for k in dict(myList + otherList).keys()]
[(1, 7), (2, 4), (3, 8), (5, 11), (7, 8)]
>>>
测试了Python2.7和3.2
dict(myList + otherList).keys()
返回一个包含连接列表的一组键的iterable
sum(...)
使'k'再次循环通过连接列表并添加元组项'v',其中k == x
...但额外的循环增加了处理开销。使用Sven Marnach提出的显式字典可以避免它。