I have 2 lists, I want to merge them, answer should be like below

Viewed 101

I have two lists of dictionaries and I'd like to merge them. When a dictionary is present in both lists, I'd like to add a "confidence" key to the dictionary to reflect that the dictionary was present in both lists.

List-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'}
]

List-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'}
]

when i run below code i am not getting proper output

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)

OUTPUT should like

[
    {'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'}
]
5 Answers

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 will be your result

You can use set comprehension to collect the "key" elements of each dictionary in your list. Then you can loop through all keys and check whether a key is in both lists.

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)

You can avoid raw loops entirely using the intersection and symmetric_difference function on set:

# 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)]

Will result in:

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

Note, that the element order will change, as they went through a set.

If you are not too worried about performance.

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))

Another approach can be:

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)

Output:

[{'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'}]
Related