这是一个有趣的解决问题的方法,这是一个强大的函数,返回一个生成器:
def combine_item_pairs(l1, l2):
D = {k:[v, False] for k, v in l1}
for key, value in l2:
if key in D:
D[key][1] = value
else:
D[key] = [False, value]
return (tuple([key]+value) for key, value in D.iteritems())
使用它:
>>> list(combine_item_pairs(list_a, list_b))
[('item_2', 'attribute_y', False), ('item_3', 'attribute_z', 'attribute_p'), ('item_1', 'attribute_x', 'attribute_n')]
这是一个额外的奖励解决方案(相同的接口,但更有效率的解决方案):
from itertools import groupby
from operator import itemgetter as I
def combine_item_pairs(l1, l2):
return (tuple(list([k]+[I(1)(i) for i in g]+[False])[:3]) for k, g in groupby(sorted(l1+l2), key=I(0)))
结果:
>>> list(combine_item_pairs(list_a, list_b))
[('item_1', 'attribute_n', 'attribute_x'), ('item_2', 'attribute_y', False), ('item_3', 'attribute_p', 'attribute_z')]
注意: 如果需要对列表进行大量排序或如果存在许多值缺失,则此解决方案的效率会降低。(此外,目前所有缺失都仅在元组的最后一项中反映为False
值,无法知道哪个列表缺少项目(这是效率的代价)。当不太重要知道哪个列表缺少项目时,应使用此解决方案处理大型数据。)
编辑:
计时器:
a = [('item_1', 'attribute_x'), ('item_2', 'attribute_y'), ('item_3', 'attribute_z')]
b = [('item_1', 'attribute_n'), ('item_3', 'attribute_p')]
def inbar(l1, l2):
D = {k:[v, False] for k, v in l1}
for key, value in l2:
if key in D:
D[key][1] = value
else:
D[key] = [False, value]
return (tuple([key]+value) for key, value in D.iteritems())
def solus(l1, l2):
dict_a,dict_b = dict(l1), dict(l2)
items = sorted({i for i,_ in l1+l2})
return [(i, dict_a.get(i,False), dict_b.get(i,False)) for i in items]
import timeit
print timeit.Timer('inbar(a, b)', 'from __main__ import a, b, inbar').repeat()
print timeit.Timer('solus(a, b)', 'from __main__ import a, b, solus').repeat()
item_1
是可哈希的吗? - Ashwini Chaudhary