在一个条件下总结两个元组列表
Summing up two lists of tuples on a condition
我们有两个长度可能不同的元组列表,如下所示:
list1 = [(15339456, 140), (15340320, 412), (15341184, 364), (15342048, 488),
(15342912, 272), (15343776, 350), (15344640, 301), (15345504, 159),
(15346368, 224), (15347232, 241), (15348096, 223), (15348960, 175)]
list2 = [(15339456, 1516), (15341184, 2046), (15342048, 2400), (15342912, 8370),
(15343776, 2112), (15344640, 1441), (15345504, 784), (15346368, 1391)]
每个元组的第一个元素是键,在每个列表中都是唯一的。我们不能假设密钥存在于两个列表中。一个列表可以包含带有另一个列表中没有的键的元素。现在我们想要总结元组的第二个值,如果它的键在两个列表中,否则我们取完整的元组。
结果:
[(15339456, 1656),
(15340320, 412),
(15341184, 2410),
...
]
通常使用 zip
总结列表,例如:
for tup1, tup2 in zip(list1, list2):
sum_ = tup1[1] + tup2[1]
lst.append((tup1[0], sum_))
如果两个列表的长度相同并且每个键都存在于两个列表中,那将可行,但情况并非如此。
在这个 for
循环中是否有建立条件的好方法?或者可能是这个的 pythonic 解决方案?两个 for
循环和元素明智的比较似乎不太令人满意。
一个明显的解决方案是创建一个结果字典,然后添加第一个列表中的所有值,然后添加第二个列表中的所有值:
from collections import defaultdict
result = defaultdict(int)
for key, value in list1:
result[key] += value
for key, value in list2:
result[key] += value
# convert dictionary-like to list of tuples if you want
result = list(result.items())
使用字典作为结果可以让您免于进行线性搜索以找到要添加值的键(导致整体二次复杂度),并且 defaultdict
特别可以让您免于做
if key not in result:
result[key] = 0
在添加第一个值之前初始化结果。
您可以使用 itertools.chain
:
将其概括为任意数量的输入列表
from collections import defaultdict
from itertools import chain
input_lists = [list1, list2]
result = defaultdict(int)
for key, value in chain.from_iterable(input_lists):
result[key] += value
视觉上现在只有一个 for
循环,但实际上它在做同样的事情。
我们有两个长度可能不同的元组列表,如下所示:
list1 = [(15339456, 140), (15340320, 412), (15341184, 364), (15342048, 488),
(15342912, 272), (15343776, 350), (15344640, 301), (15345504, 159),
(15346368, 224), (15347232, 241), (15348096, 223), (15348960, 175)]
list2 = [(15339456, 1516), (15341184, 2046), (15342048, 2400), (15342912, 8370),
(15343776, 2112), (15344640, 1441), (15345504, 784), (15346368, 1391)]
每个元组的第一个元素是键,在每个列表中都是唯一的。我们不能假设密钥存在于两个列表中。一个列表可以包含带有另一个列表中没有的键的元素。现在我们想要总结元组的第二个值,如果它的键在两个列表中,否则我们取完整的元组。
结果:
[(15339456, 1656),
(15340320, 412),
(15341184, 2410),
...
]
通常使用 zip
总结列表,例如:
for tup1, tup2 in zip(list1, list2):
sum_ = tup1[1] + tup2[1]
lst.append((tup1[0], sum_))
如果两个列表的长度相同并且每个键都存在于两个列表中,那将可行,但情况并非如此。
在这个 for
循环中是否有建立条件的好方法?或者可能是这个的 pythonic 解决方案?两个 for
循环和元素明智的比较似乎不太令人满意。
一个明显的解决方案是创建一个结果字典,然后添加第一个列表中的所有值,然后添加第二个列表中的所有值:
from collections import defaultdict
result = defaultdict(int)
for key, value in list1:
result[key] += value
for key, value in list2:
result[key] += value
# convert dictionary-like to list of tuples if you want
result = list(result.items())
使用字典作为结果可以让您免于进行线性搜索以找到要添加值的键(导致整体二次复杂度),并且 defaultdict
特别可以让您免于做
if key not in result:
result[key] = 0
在添加第一个值之前初始化结果。
您可以使用 itertools.chain
:
from collections import defaultdict
from itertools import chain
input_lists = [list1, list2]
result = defaultdict(int)
for key, value in chain.from_iterable(input_lists):
result[key] += value
视觉上现在只有一个 for
循环,但实际上它在做同样的事情。