我有2个元组列表
a = [(123, 0, 1), (245, 0, 1)]
b = [(123, 1, 0), (678, 1, 0)]
我想以这样的方式合并这两个列表:我的输出是:
merged_list = [(123, 1, 1), (245, 0, 1), (678, 1,0)]
我找到了这段代码
def inner_join(a, b):
L = a + b
L.sort(key=itemgetter(0)) # sort by the first column
for _, group in groupby(L, itemgetter(0)):
row_a, row_b = next(group), next(group, None)
if row_b is not None: # join
yield row_a + row_b[1:]
当我执行它时,它返回第一个元素是常见的元组
result = list(inner_join(a,b))
result - [(123,1,1)]
如何解决这个问题,以便我能够获得所需的解决方案
[(123, 1, 1), (245, 0, 1), (678, 1,0)]
答案 0 :(得分:2)
您可以使用itertools.groupby
根据元组的第一个值对相似元素进行分组。
a = [(123, 0, 1), (245, 0, 1)]
b = [(123, 1, 0), (678, 1, 0)]
from itertools import groupby
grouped_list = [(k,list(g)) for k,g in groupby(sorted([*a,*b]),key= lambda x: x[0])]
这将为您提供如下输出:
[(123, [(123, 0, 1), (123, 1, 0)]), (245, [(245, 0, 1)]), (678, [(678, 1, 0)])]
接下来,我们需要对分组列表中元组的第二个和第三个值求和,以获得所需的输出。
out = [(k,*[sum(x) for x in zip(*x)][1:]) for k,x in grouped_list]
这将为您提供所需的输出
[(123, 1, 1), (245, 0, 1), (678, 1, 0)]
如果您更喜欢单行:
[(k,*[sum(x) for x in zip(*list(g))][1:]) for k,g in itertools.groupby(sorted([*a,*b]),key=lambda x: x[0])]
答案 1 :(得分:1)
听起来你想使用每个元组的第一个值作为键,在这种情况下,将元组a更改为字典可能更实用。我确信有更好的方法,但你可以试试这个。而不是
a = [(123, 0, 1), (245, 0, 1)]
尝试
a_dic = {123: (0,1), 245: (0,1)}
然后,您可以根据字典中的键检查b(元组列表)。如果未找到匹配项,则将新键和值添加到字典中。如果键匹配则添加其值。
for x in b:
temp_tuple = x[1], x[2]
if not x[0] in a_dic.keys():
a_dic.update({x[0]: temp_tuple})
else:
new_value = tuple(map(sum,zip(temp_tuple, a_dic.get(x[0]))))
a_dic.update({x[0]:new_value})
print(a_dic)
结果是:
{123: (1, 1), 245: (0, 1), 678: (1, 0)}
答案 2 :(得分:0)
检查一下。这是工作。您可以根据需要更改/调整代码。希望代码足够简单易懂。
a = [(123, 0, 1), (245, 0, 1)]
b = [(123, 1, 0), (678, 1, 0)]
# print (a)
# print (b)
c1=[]
c=[]
for element1 in b:
c1.append(element1)
for element2 in a:
if element1[0]==element2[0]:
x=(element1[0],element1[1]+element2[1],element1[2]+element2[2])
c.append(x)
for element2 in a:
c1.append(element2)
for element in c1:
flag=0
for element1 in c:
if element1[0]==element[0]:
flag=1
if (flag==0):
c.append(element)
print(c)