对于一个通用的解决方案,请考虑以下内容。即使用户在列表中顺序不同,它也会正确地进行差异比较。
def dict_diff ( merge, lhs, rhs ):
"""Generic dictionary difference."""
diff = {}
for key in lhs.keys():
if (key not in rhs):
diff[key] = lhs[key]
elif (lhs[key] != rhs[key]):
diff[key] = merge(lhs[key], rhs[key])
for key in rhs.keys():
if (key not not lhs):
diff[key] = rhs[key]
return diff
def user_diff ( lhs, rhs ):
"""Merge dictionaries using value from right-hand-side on conflict."""
merge = lambda l,r: r
return dict_diff(merge, lhs, rhs)
import copy
def push ( x, k, v ):
"""Returns copy of dict `x` with key `k` set to `v`."""
x = copy.copy(x); x[k] = v; return x
def pop ( x, k ):
"""Returns copy of dict `x` without key `k`."""
x = copy.copy(x); del x[k]; return x
def special_diff ( lhs, rhs, k ):
lhs = dict([(D[k],pop(D,k)) for D in lhs])
rhs = dict([(D[k],pop(D,k)) for D in rhs])
c = dict_diff(user_diff, lhs, rhs)
return [push(D,k,K) for (K,D) in c.items()]
然后,您可以检查解决方案:
ldA = [{'user':"nameA", 'a':7.6, 'b':100.0, 'c':45.5, 'd':48.9},
{'user':"nameB", 'a':46.7, 'b':67.3, 'c':0.0, 'd':5.5}]
ldB =[{'user':"nameA", 'a':7.6, 'b':99.9, 'c':45.5, 'd':43.7},
{'user':"nameB", 'a':67.7, 'b':67.3, 'c':1.1, 'd':5.5},
{'user':"nameC", 'a':89.9, 'b':77.3, 'c':2.2, 'd':6.5}]
import pprint
if __name__ == '__main__':
pprint.pprint(special_diff(ldA, ldB, 'user'))
user
是一个特殊键吗?它用于建立列表项之间的对应关系(假设ldB
是无序的,结果是否应该相同)? - André CaronldA = {'userA': {'a': 1, 'b': 2, ...}, ...}
。 - Karl Knechtel