【问题标题】:Compare two dictionaries with list of values which satisfies multiple conditions将两个字典与满足多个条件的值列表进行比较
【发布时间】:2023-03-26 01:51:02
【问题描述】:

我想比较两个具有如下值列表的字典:

dict1 = {'111': [], '333': ['a@a.com'], '444': ['b@b.com', 'c@c.com'], '555': ['d@d.com']}
dict2 = {'111': ['e@e.com'], '333': ['f@f.com' ], '444': ['b@b.com', 'g@g.com'], '555': ['d@d.com']}

并创建满足以下条件的结果字典(result_dict):

  1. dict1 中不存在特定键的 dict2 值添加到 result_dict
  2. 如果 dict1 和 dict2 的值相同,则不需要在 result_dict 中添加该键(例如应该跳过 555)

生成的 dict 应如下所示:

   dict3 = {'1111': ['e@e.com'], '333': ['f@f.com'], '444': ['g@g.com']}

我有以下代码

    result_dict = {}
    for k,v in dict2.items():
        for k1,v1 in dict1.items():
            if k == k1 and v != v1:
               result_dict[k] = v


    print(result_dict)

哪些输出:

{'111': ['e@e.com'], '333': ['f@f.com'], '444': ['b@b.com', 'g@g.com']}

在上述情况下,它不应该为 444 添加'b@b.com'。如果为 eg 更改订单,它也会给出不正确的结果

'444': ['b@b.com', 'c@c.com']
'444': ['c@c.com', 'b@b.com']

对 dict 值进行排序将无济于事,因为在某些情况下,dict1 的值比 dict2 的值更多。我正在使用 Python 3.7。任何帮助将不胜感激

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    如果您想在result_dict 中保持与原始字典中相同的顺序(我的意思是dict2):

    result_dict = {
        k: v if k not in dict1 else [a for a in v if a not in dict1[k]]
        for k, v in filter(lambda x: len(set(x[1]).difference(dict1.get(x[0], []))), dict2.items())
    }
    

    这里result_dict

    {'111': ['e@e.com'], '333': ['f@f.com'], '444': ['g@g.com']}
    

    输出字典由dict comprehension 创建。基本上,我们选择dict2 中的键,其值是与dict1 中的对应列表相比具有至少一个原始元素的列表。然后,清除所选键的列表,删除也存在于dict1 的对应列表中的元素。特别是:

    • filter(lambda x: len(set(x[1]).difference(dict1.get(x[0], []))), dict2.items()) }:仅循环遍历dict2 的键/列表,其中至少有一个元素不在dict1 的对应列表中。
    • k: v if k not in dict1 else [a for a in v if a not in dict1[k]] 在新字典中创建一个与dict2 相同键的条目,并将dict2 中的相应列表作为值,如果键不在dict1 中,否则创建一个新列表(使用list comprehension)循环遍历dict2 列表中的项目并删除dict1 中对应列表中的项目(这将保留dict2 中原始列表的顺序。

    【讨论】:

    • 谢谢,这正是我想要的
    • 你能解释一下这里发生了什么吗?它看起来很密集@PieCot
    • @AjayMisra 我已经更新了答案。不要害怕问是否不够清楚。
    【解决方案2】:

    您可以过滤掉任何值匹配的项目,然后在 dict 理解中,新键应该是对应键的 set.difference

    >>> {k:list(set(v).difference(dict1[k])) for k,v in dict2.items() if dict1[k] != v}
    {'111': ['e@e.com'], '333': ['f@f.com'], '444': ['g@g.com']}
    

    【讨论】:

      猜你喜欢
      • 2011-07-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      相关资源
      最近更新 更多