【问题标题】:I have 2 lists, I want to merge them, answer should be like below我有 2 个列表,我想合并它们,答案应该如下所示
【发布时间】:2021-11-13 19:49:01
【问题描述】:

我有两个字典列表,我想合并它们。当两个列表中都存在字典时,我想在字典中添加一个“信心”键,以反映该字典存在于两个列表中。

列表 1

lst1 = [
    {'key': 'data_collected.service_data'},
    {'key': 'gdpr.gdpr_compliance'},
    {'key': 'disclosure_of_information.purpose_of_disclosure'},
    {'key': 'opt_out.choice_of_opt_out'}
]

列表 2

lst2 = [
    {'key': 'child_data_protection.parent_guardian_consent'},
    {'key': 'ccpa.ccpa_compliance'},
    {'key': 'disclosure_of_information.purpose_of_disclosure'},
    {'key': 'opt_out.choice_of_opt_out'}
]

当我在代码下面运行时,我没有得到正确的输出

res = []
for x in lst1:
    for y in lst2:
        if x["key"] == y["key"]:
            if x not in res and y not in res:
                res.append({"key": x["key"], "confidence": 1})
        else:
            if x not in res and y not in res:
                res.append(x)
                res.append(y)

print(res)

输出应该喜欢

[
    {'key': 'data_collected.service_data'},
    {'key': 'gdpr.gdpr_compliance'},
    {
        'key': 'disclosure_of_information.purpose_of_disclosure',
        'confidence': 1
    },
    {
        'key': 'opt_out.choice_of_opt_out',
        'confidence': 1
    },
    {'key': 'child_data_protection.parent_guardian_consent'},
    {'key': 'ccpa.ccpa_compliance'}
]

【问题讨论】:

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


    【解决方案1】:

    您可以使用set comprehension 收集列表中每个字典的“关键”元素。然后你可以遍历所有键并检查一个键是否在两个列表中。

    keys_1 = {d["key"] for d in lst1}
    keys_2 = {d["key"] for d in lst2}
    
    output = []
    for k in keys_1 | keys_2:
        d = {"key": k}
        if k in keys_1 and k in keys_2:
            d["confidence"] = 1
        output.append(d)
    

    【讨论】:

      【解决方案2】:

      您可以使用set 上的intersectionsymmetric_difference 函数完全避免原始循环:

      # Shortened key names for brevity
      a = [{"key": "a"}, {"key": "b"}, {"key": "c"}]
      b = [{"key": "a"}, {"key": "d"}, {"key": "e"}]
      
      # Turn both lists into sets
      a_keys = {entry["key"] for entry in a}
      b_keys = {entry["key"] for entry in b}
      
      # Add elements that are in both sets with confidence set to 1
      result = [{"key": key, "confidence": 1} for key in a_keys.intersection(b_keys)]
      # Add elements that are not in both sets
      result += [{"key": key} for key in a_keys.symmetric_difference(b_keys)]
      

      将导致:

      [{'confidence': 1, 'key': 'a'},
       {'key': 'b'},
       {'key': 'd'},
       {'key': 'c'},
       {'key': 'e'}]
      

      请注意,元素顺序会随着set 而改变。

      【讨论】:

        【解决方案3】:

        lst1.extend(i for i in (i if i not in lst1 else lst1[lst1.index(i)].update({'confidence': 1}) for i in lst2) if i is not None)

        lst1 将是你的结果

        【讨论】:

        • 小优化:使用生成器表达式而不是列表推导式,以避免在内存中构建临时副本。即,使用lst1.extend(i for i in lst2 if i not in lst1),不使用[]
        • 更大的问题:我不完全理解 OP 对 confidence 字段的意图,但你没有添加它,所以我想你一定没有在问题中注意到它。
        • @joanis 感谢您的注释,重新编辑它,但仍然需要列表理解,知道吗?
        • 只需将 [...] 转换为 (...): lst1.extend(i for i in (i if i not...。这是一个关于 genator expressions and list comprehensions 和出色的 tutorial by Trey Hunner 之间区别的 SO 问题,它帮助我真正理解了与 Python 相关的所有理解。 --(注意:我不隶属于 Trey Hunner,但我对他的 Python Morsels 非常满意。)
        • @joanis 也感谢您的评论
        【解决方案4】:

        如果您不太担心性能。

        intersection = [value for value in lst1 if value in lst2]
        res = [val for val in lst1 if val not in intersection] + [val for val in lst2 if val not in intersection]
        res += list(map(add_confidence, intersection))
        

        【讨论】:

          【解决方案5】:

          另一种方法可以是:

          lst1 = [
              {'key': 'data_collected.service_data'},
              {'key': 'gdpr.gdpr_compliance'},
              {'key': 'disclosure_of_information.purpose_of_disclosure'},
              {'key': 'opt_out.choice_of_opt_out'}
          ]
          lst2 = [
              {'key': 'child_data_protection.parent_guardian_consent'},
              {'key': 'ccpa.ccpa_compliance'},
              {'key': 'disclosure_of_information.purpose_of_disclosure'},
              {'key': 'opt_out.choice_of_opt_out'}
          ]
          for data in lst1:
              # If same data exists in lst2, add confidence key and remove it from lst2
              if data in lst2:
                  lst2.remove(data)
                  data['confidence']=1
          
          # At the end of above for loop, lst2 contains unique data, now just add both the lists to get the final result            
          lst1 = lst1+lst2        
          print (lst1)
          

          输出:

          [{'key': 'data_collected.service_data'}, {'key': 'gdpr.gdpr_compliance'}, {'key': 'disclosure_of_information.purpose_of_disclosure', 'confidence': 1}, {'key': 'opt_out.choice_of_opt_out', 'confidence': 1}, {'key': 'child_data_protection.parent_guardian_consent'}, {'key': 'ccpa.ccpa_compliance'}]
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2022-01-22
            • 1970-01-01
            • 1970-01-01
            • 2020-10-07
            • 2020-04-03
            • 2020-07-26
            相关资源
            最近更新 更多