我有如下列表
a=[['a',1,2,1,3],['b',1,3,4,3],['c',1,3,4,3]]
b=[['b',1,3,4,3],['c',1,3,4,3]]
如果第一个子列表元素与其他列表子列表元素匹配,我想基于索引添加元素
尝试以下内容:
from operator import add
res_list1=[]
for a1 in a:
for b1 in b:
if a1[0]==b1[0]:
res_list = [map(add, a1[1:], b1[1:])]
res = [[a1[0],i,j,k,l] for i,j,k,l in res_list]
res_list1.append(res[0])
else:
res_list=a1
res_list1.append(res_list)
print res_list1
但输出结果如下:
res_list1=[['a', 1, 2, 1, 3], ['a', 1, 2, 1, 3], ['b', 2, 6, 8, 6], ['b', 1, 3, 4, 3], ['c', 1, 3, 4, 3], ['c', 2, 6, 8, 6]]
但正确的输出应该是:
res_list1=[['a', 1, 2, 1, 3], ['b', 2, 6, 8, 6], ['c', 2, 6, 8, 6]]
答案 0 :(得分:3)
这是一种基于itertools
的方法:
from operator import itemgetter
from itertools import groupby, islice
l = sorted(a+b)
[[k] + [sum(i) for i in islice(zip(*v),1,None)] for k,v in groupby(l, key=itemgetter(0))]
# [['a', 1, 2, 1, 3], ['b', 2, 6, 8, 6], ['c', 2, 6, 8, 6]]
答案 1 :(得分:2)
您可以定义一个像这样的函数:
def add_elements(a, b):
b_dict = {i[0]: i[1:] for i in b}
default = [0 for _ in a][:-1]
return [i[:1] + [sum(x) for x in zip(i[1:], b_dict.get(i[0], default))] for i in a]
并使用您的列表作为参数调用它:
add_elements(a, b)
#[['a', 1, 2, 1, 3], ['b', 2, 6, 8, 6], ['c', 2, 6, 8, 6]]
答案 2 :(得分:2)
请参阅@zipa的答案,以获得使用字典的更Pythonic(高效,简短,易读,总体上更好的解决方案)。
我将尝试使用您自己的代码的原始结构来回答:
from operator import add
a=[['a',1,2,1,3],['b',1,3,4,3],['c',1,3,4,3]]
b=[['b',1,3,4,3],['c',1,3,4,3]]
res_list1=[]
for a1 in a:
found_match = False
for b1 in b:
if a1[0]==b1[0]:
found_match = True
res_list = [map(add, a1[1:], b1[1:])]
res = [[a1[0],i,j,k,l] for i,j,k,l in res_list]
res_list1.append(res[0])
if not found_match:
res_list = a1
res_list1.append(res_list)
print(res_list1)
您遇到的问题始终是内部循环的每次迭代(因此,每对res_list1
对都附加到(a1,b1)
)。
我要做的是“记住”(即-保留一个布尔变量)我们是否在a1
中找到了b
的匹配项,并且只有在没有找到时-将原始列表添加到结果中