【问题标题】:Compute difference between list-of-dicts, return dict with new keys and old values计算字典列表之间的差异,返回带有新键和旧值的字典
【发布时间】:2018-01-23 18:31:07
【问题描述】:

我想映射两个字典列表之间的差异。

我正在使用 Python 3.5,并且想知道获取集合之间差异的最佳方法。我知道集合操作,但我不确定这是否是在我目前的情况下实现它们的最佳方式。

这是我现在拥有的:

orig = set()
chng = set()

original = [{"name": "Tom Pety", "name_id": 1}, {"name": "Tom Cruz", "name_id": 2}]
changed = [{"name": "Tom Petty"}, {"name": "Tom Cruise"}]

for item in original:
    orig.update(item.values())

for item in changed:
    chng.update(item.values())

diffs = orig - chng

我当前的输出是{'Tom Pety', 1, 2, 'Tom Cruz'}

最终,我希望得到一个看起来像这样的结果,以便将更改的值与它们的 id 相关联:

[{"name": "Tom Petty", "name_id": 1}, {"name": "Tom Cruise", "name_id": 2}]

最好的方法是什么?

【问题讨论】:

  • originalchanged 列表的顺序是否相同?
  • 我不明白你在做什么。您想要的输出与您的原始输入相同。
  • @DanielRoseman:不,请检查姓名的拼写。
  • 我不关注:name_id 字段没有改变,但您在输出中列出了它们。
  • @StefanPochmann - 我不确定 set 是否是解决这个问题的最佳方法,或者说我是不是找错了树。

标签: python python-3.x list dictionary nested


【解决方案1】:

如果列表具有相同的顺序(这意味着changed第一个项必须应用于第一个original 等),那么我们可以使用 zip 并发地遍历列表,并使用 dict.update 函数同时更新这些列表。喜欢:

for orig, chang in zip(original, changed):
    orig.update(chang)

在此之后,orig 列表将包含一个带有字典的列表:

>>> original
[{'name': 'Tom Petty', 'name_id': 1}, {'name': 'Tom Cruise', 'name_id': 2}]

请注意,我们更新字典,我们构造新字典。如果我们需要创建新的,例如,我们可以使用以下方法:

new_list = [ {**orig, **chang} for orig, chang in zip(original, changed) ]

此字典语法已在 PEP-448 中引入, 中支持(但不支持)3.5。

【讨论】:

  • 对于上面的例子,我假设列表是正确排序的。如果没有正确订购,我知道找到差异会更加困难?
  • @unseen_damage:问题在于修复是什么变得非常模糊。假设您在original = [{'name': 'Leonardo'}]changed = [{'name': 'Leonardo Da Vinci'}, {'name': 'Leonardo DiCaprio'}] 中选择哪一个?此外,我们怎么知道原来的错误?根据什么衡量标准,我们决定哪种修复是最好的?没有正确答案。
  • 在这种情况下您有什么建议?请注意 address_country 已更改,但我没有得到所需的输出:original = [{'postal_code': '85043', 'address_id': 1, 'state': 'AZ', 'address': '123 my road', 'city': 'PHONEIX', 'address_country': None}]changed = [{'postal_code': '85043', 'city': 'PHONEIX', 'address_country': 'United States of America', 'state': 'AZ', 'address': '123 my road'}] 我的输出如下所示:new list [{'address_id': 1, 'address_country': None, 'state': 'AZ', 'address': '123 my road', 'postal_code': '85043', 'city': 'PHONEIX'}]
  • 我得到了(两种方法[{'city': 'PHONEIX', 'address_id': 1, 'address_country': 'United States of America', 'address': '3037 S. 69TH DRIVE', 'postal_code': '85043', 'state': 'AZ'}])。
猜你喜欢
  • 1970-01-01
  • 2019-12-14
  • 1970-01-01
  • 1970-01-01
  • 2019-10-06
  • 1970-01-01
  • 2021-12-09
  • 2020-04-14
  • 1970-01-01
相关资源
最近更新 更多