获取两个字典列表之间的差异(结果为两个差异列表)
Get differences between two lists of dictionaries (result as two differences lists)
编辑: 我需要一个适用于字典列表的解决方案(字典不可哈希),所以这不是 Compute list difference[=17= 的副本]
我有两个词典列表。它们包含 gmail 标签/过滤器。我需要以两个差异列表的形式获取它们之间的差异。我希望保留元素的顺序。
示例:
a=[
{'name': 'label_a'},
{'color': {'background': '#42d692', 'text': '#094228'}, 'name': 'label_b'},
{'name': 'label_d'},
{'name': 'label_e'},
]
b=[
{'name': 'label_a'},
{'name': 'label_b'},
{'name': 'label_c'},
{'name': 'label_d'},
]
预期结果:
a_diff=[
{'color': {'background': '#42d692', 'text': '#094228'}, 'name': 'label_b'},
{'name': 'label_e'},
]
b_diff=[
{'name': 'label_b'},
{'name': 'label_c'},
]
这是我可以做到的,但我认为它可能效率低下。我可以做得更好吗?
a_diff=[]
b_diff=[]
for i in a:
if i not in b:
a_diff.append(i)
for j in b:
if j not in a:
b_diff.append(j)
此操作后我不需要保留原始列表,因此可以就地使用。速度是最重要的。所以这个问题也可以改写为:“如何从这些列表中删除两个列表之间的公共元素?”
当您提供解决方案时,请告知它是否也适用于任何两个列表或仅适用于字典列表。
另请告知您的解决方案是否会删除重复项(我对这两种解决方案都感兴趣):
示例:
a=[
{'name': 'label_a'},
{'name': 'label_a'},
{'name': 'label_b'},
]
b=[
{'name': 'label_a'},
{'name': 'label_b'},
{'name': 'label_c'},
]
删除了重复项的结果:
a_diff=[
]
b_diff=[
{'name': 'label_c'},
]
没有删除重复项的结果:
a_diff=[
{'name': 'label_a'},
]
b_diff=[
{'name': 'label_c'},
]
这种方法有点奇怪,但它确实有效:
def make_hash(list_of_dicts):
return {str(d): i for i, d in enumerate(list_of_dicts)}
def ordered_diff(d1, d2):
return [eval(d) for d in sorted(d1.keys() - d2, key=d1.get)]
def get_diff(l1, l2):
d1, d2 = make_hash(l1), make_hash(l2)
return ordered_diff(d1, d2), ordered_diff(d2, d1)
编辑: 我需要一个适用于字典列表的解决方案(字典不可哈希),所以这不是 Compute list difference[=17= 的副本]
我有两个词典列表。它们包含 gmail 标签/过滤器。我需要以两个差异列表的形式获取它们之间的差异。我希望保留元素的顺序。
示例:
a=[
{'name': 'label_a'},
{'color': {'background': '#42d692', 'text': '#094228'}, 'name': 'label_b'},
{'name': 'label_d'},
{'name': 'label_e'},
]
b=[
{'name': 'label_a'},
{'name': 'label_b'},
{'name': 'label_c'},
{'name': 'label_d'},
]
预期结果:
a_diff=[
{'color': {'background': '#42d692', 'text': '#094228'}, 'name': 'label_b'},
{'name': 'label_e'},
]
b_diff=[
{'name': 'label_b'},
{'name': 'label_c'},
]
这是我可以做到的,但我认为它可能效率低下。我可以做得更好吗?
a_diff=[]
b_diff=[]
for i in a:
if i not in b:
a_diff.append(i)
for j in b:
if j not in a:
b_diff.append(j)
此操作后我不需要保留原始列表,因此可以就地使用。速度是最重要的。所以这个问题也可以改写为:“如何从这些列表中删除两个列表之间的公共元素?”
当您提供解决方案时,请告知它是否也适用于任何两个列表或仅适用于字典列表。
另请告知您的解决方案是否会删除重复项(我对这两种解决方案都感兴趣):
示例:
a=[
{'name': 'label_a'},
{'name': 'label_a'},
{'name': 'label_b'},
]
b=[
{'name': 'label_a'},
{'name': 'label_b'},
{'name': 'label_c'},
]
删除了重复项的结果:
a_diff=[
]
b_diff=[
{'name': 'label_c'},
]
没有删除重复项的结果:
a_diff=[
{'name': 'label_a'},
]
b_diff=[
{'name': 'label_c'},
]
这种方法有点奇怪,但它确实有效:
def make_hash(list_of_dicts):
return {str(d): i for i, d in enumerate(list_of_dicts)}
def ordered_diff(d1, d2):
return [eval(d) for d in sorted(d1.keys() - d2, key=d1.get)]
def get_diff(l1, l2):
d1, d2 = make_hash(l1), make_hash(l2)
return ordered_diff(d1, d2), ordered_diff(d2, d1)