【问题标题】:python difference between 2 lists of dictionaries by a key2个字典列表之间的python区别键
【发布时间】:2021-02-05 16:18:49
【问题描述】:

我有 2 个类似于以下的字典列表:

a = [
     {'username': 'user1', 'is_admin': False}, 
     {'username': 'user2', 'is_admin': True}, 
     {'username': 'user3', 'is_admin': True}
    ]

b = [
     {'username': 'user1', 'is_admin': False}, 
     {'username': 'user2', 'is_admin': False}, 
     {'username': 'user4', 'is_admin': True}
    ]

现在,我想比较这两个列表并获取如下数据:

difference between a and b =
{'added': 
    [{'username': 'user4', 'is_admin': True}], 
 'removed': 
    [{'username': 'user3', 'is_admin': True}], 
 'updated': 
    [{'username': 'user2', 'is_admin': False}], 
  'unchanged': 
    [{'username': 'user1', 'is_admin': False}]]
 }

说明:用户4被添加到b列表中,用户3从b列表中移除并且用户2的值被更新(is_admin字段)并且用户1保持不变。

我可以选择遍历其中一个列表并在其他列表中搜索每个“用户名”键。但这似乎不是有效的选择(在每个循环中搜索所有数组)。

有没有有效的方法来解决这个问题?

【问题讨论】:

  • 你检查this了吗?
  • 是的,我试过这个。但这不适用于“更新”之类的情况,其中用户名“user2”的值已从 is_admin true 更改为 false。
  • 这些是带有字典列表。 Python != Javascript
  • @juanpa.arrivillaga 好的。
  • 尝试unittest.TestCase.assertListEqual 方法。它提供了详细的差异。

标签: python arrays lambda


【解决方案1】:

我尝试了以下代码并且它有效。 我在这里所做的是找到 b 中存在而 a 中不存在的字典(添加列表)。然后是 a 中存在但 b 中不存在的已删除 dict(已删除列表)。由于 a 和 b 中的“user2”不完全相同(已更新),“user2”的数据将同时出现在添加和删除列表中,因此在下一步中,我找到了添加和删除列表中都存在的用户名列表然后从添加和删除列表中删除 dict,该列表中的用户名存在于更新的用户名列表中。

a = [
     {'username': 'user1', 'is_admin': False}, 
     {'username': 'user2', 'is_admin': True}, 
     {'username': 'user3', 'is_admin': True}
    ]

b = [
     {'username': 'user1', 'is_admin': False}, 
     {'username': 'user2', 'is_admin': False}, 
     {'username': 'user4', 'is_admin': True}
    ]

added = [i for i in b if i not in a]
removed = [i for i in a if i not in b]
unchanged = [i for i in a if i in b]
updated_usernames = [i 
                    for i in list(i['username'] for i in added) 
                    if i in list(i['username'] for i in removed)]
updated = []
for i in added:
    if i['username'] in updated_usernames:
        added.remove(i)
        updated.append(i)
for i in removed:
    if i['username'] in updated_usernames:
        removed.remove(i)

difference_between_a_and_b = {'added': added, 
 'removed': removed, 
 'updated': updated, 
  'unchanged': unchanged
 }

print(difference_between_a_and_b)

我得到的输出

【讨论】:

  • 谢谢...似乎工作。我明天再测试一下。
  • 不客气。如果您在测试时发现任何问题,请将其添加为评论,我会尽力修复它?。
【解决方案2】:

您肯定需要遍历列表。为了提高效率,您可以从前两个列表(或它们的副本)中删除选中的元素,并在找到要处理的元素后中断嵌套循环。我认为这将显着提高效率。

示例(伪代码):

while a or b:
  x = pop(a)
  y = pop(b)
  # compare x and y (try to use built-in methods such as map, filter etc. to make it fast)
  # append to one of the differences dictionary's list 

【讨论】:

    猜你喜欢
    • 2016-08-16
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 2014-10-22
    • 2020-12-24
    • 2012-06-24
    • 1970-01-01
    相关资源
    最近更新 更多