Python: merging two lists where object “identity” isn't equality
我试图合并两个列表,
1 2 3 4 5 6 7 8 9 10 | # Part of a function final = [] for i in base: if all((i.al2000, i.de2000) != (k.al2000, k.de2000) for k in override): final.append(i) else: for k in override: if (i.al2000, i.de2000) == (k.al2000, k.de2000): final.append(k) return final |
你可以用字典和一些字典的理解。
1 2 3 | uniques = {(x.al2000, x.de2000): x for x in base} uniques.update({(x.al2000, x.de2000): x for x in override}) final = uniques.values() |
号
编辑以保留在
1 2 3 4 5 6 7 8 | uniques = {(x.al2000, x.de2000): x for x in base} for value in override: key = value.al2000, value.de2000 if key in uniques: uniques[key] = value # here's the comprehension version, although it's a bit rough on the eyes # uniques.update({(x.al2000, x.de2000): x for x in override if (x.al2000, x.de2000) in uniques}) final = uniques.values() |
您可以使用
1 2 3 4 5 6 7 8 9 | final = [] for i in base: for k in override: if (i.al2000, i.de2000) == (k.al2000, k.de2000): # found an override final.append(k) break else: final.append(i) |
此解决方案仍然使用嵌套的for循环,但它从原始解决方案中删除了代码重复(在
这个答案采纳了@acushner的建议,使用听写,这可能是您案例中最自然的方法。除此之外,在处理覆盖时,
1 2 3 4 5 6 7 8 | from collections import ChainMap base_dct = {(x.al2000, x.de2000): x for x in base} override_dct = {(x.al2000, x.de2000): x for x in override} z = ChainMap(base_dct, override_dct) # then access: z.values() # or: z[(x.al2000, x.de2000)] |
。
有关链图的详细信息,请参阅此问题。
因为您真正想做的就是在重写中查找一些内容,所以可以对其进行dict:
1 | od = {(x.al2000, x.de2000): x for x in override} |
。
现在,只需创建结果:
1 | res = [od.get((b.al2000, b.de2000), b) for b in base] |
*未测试,但应正常*为迪恩的建议而编辑