我想在两个python_lists之间执行完全外部联接。考虑它们都有相同的键:(名称和宠物)。除此之外,它们具有不同的金额,两者都应显示在result_list中。如何在python中实现?
list_a = [['John','Cat',10],
['Adam','Dog',20]]
list_b = [['John','Cat',40],
['Laura','Fish',60]]
result_list = [['John','Cat',10, 40],
['Adam','Dog',20,0],
['Laura','Fish',0, 60]]]
答案 0 :(得分:1)
您可以使用字典来更有效地执行字典操作,该方法可以比较每对列表。
list_a = [['John','Cat',10], ['Adam','Dog',20]]
list_b = [['John','Cat',40], ['Laura','Fish',60]]
d = {}
for person, pet, v in list_a + list_b:
if (person, pet) in d:
d[(person, pet)]+=v
else:
d[(person, pet)]=v
final_list = [[key[0],key[1],val] for key,val in d.items()]
输出
[['John', 'Cat', 50], ['Adam', 'Dog', 20], ['Laura', 'Fish', 60]]
注意到这不是OP要求的,然后编辑。
对于预期的输出,代码可以更改为:
list_a = [['John','Cat',10], ['Adam','Dog',20]]
list_b = [['John','Cat',40], ['Laura','Fish',60]]
d = dict(((person,pet),[v,0]) for (person,pet,v) in list_a)
for person, pet, v in list_b :
if (person, pet) in d:
d[(person, pet)][1] = v
else:
d[(person, pet)] = [0,v]
final_list = [[key[0],key[1],val[0],val[1]] for key,val in d.items()]
#python3.x
final_list = [[*key,*val] for key,val in d.items()]
输出:
[['John', 'Cat', 10, 40], ['Adam', 'Dog', 20, 0], ['Laura', 'Fish', 0, 60]]
答案 1 :(得分:0)
有点傻,但是一种直接的方法是从dict
逐步构建它:
d = {}
for name, pettype, val in list_a:
d[name, pettype] = [val, 0]
for name, pettype, val in list_b:
try:
d[name, pettype][1] = val
except KeyError:
d[name, pettype] = [0, val]
# Use .items() instead of .viewitems() on Python 3.x
result_list = [[name, pettype, vala, valb] for (name, pettype), (vala, valb) in d.viewitems()]
在Python 3.6之前,顺序不一致;在3.6及更高版本中,您将依次看到list_a
中的所有名称/宠物,然后依次查看list_b
中未出现在list_a
中的所有名称/宠物。
如果您真的讨厌重复自己,或者需要加入许多此类列表,则可以将其调整为:
d = {}
all_lists = [list_a, list_b, ..., list_n]
for i, curlist in enumerate(all_lists):
for name, pettype, val in curlist:
try:
vals = d[name, pettype]
except KeyError:
vals = d[name, pettype] = [0] * len(all_lists)
vals[i] = val
result_list = [[name, pettype] + vals for (name, pettype), vals in d.viewitems()]
或使用collections.defaultdict
来避免异常处理代码:
from collections import defaultdict
all_lists = [list_a, list_b, ..., list_n]
d = defaultdict(lambda: [0] * len(all_lists))
for i, curlist in enumerate(all_lists):
for name, pettype, val in curlist:
d[name, pettype][i] = val
result_list = [[name, pettype] + vals for (name, pettype), vals in d.viewitems()]