web-dev-qa-db-fra.com

Comparaison de 2 listes composées de dictionnaires avec des clés uniques en python

J'ai 2 listes, les deux contenant le même nombre de dictionnaires. Chaque dictionnaire a une clé unique. Il existe une correspondance pour chaque dictionnaire de la première liste de la deuxième liste, c'est-à-dire qu'un dictionnaire avec une clé unique existe dans l'autre liste. Mais les autres éléments de ces 2 dictionnaires peuvent varier. Par exemple:

list_1 = [
            {
                'unique_id': '001',
                'key1': 'AAA',
                'key2': 'BBB',
                'key3': 'EEE'
             },
             {
                'unique_id': '002',
                'key1': 'AAA',
                'key2': 'CCC',
                'key3': 'FFF'
             }
         ]

 list_2 = [
             {
                'unique_id': '001',
                'key1': 'AAA',
                'key2': 'DDD',
                'key3': 'EEE'
             },
             {
                'unique_id': '002',
                'key1': 'AAA',
                'key2': 'CCC',
                'key3': 'FFF'
             }
         ]

Je souhaite comparer tous les éléments de 2 dictionnaires correspondants. Si l'un des éléments n'est pas égal, je souhaite imprimer les éléments non égaux.

Pourriez-vous s'il vous plaît aider?

25
alwbtc

En supposant que les doigts s'alignent comme dans votre exemple d'entrée, vous pouvez utiliser la fonction Zip() pour obtenir une liste des paires de doigts associées, puis vous pouvez utiliser any() pour vérifier s'il y a une différence:

>>> list_1 = [{'unique_id':'001', 'key1':'AAA', 'key2':'BBB', 'key3':'EEE'}, 
              {'unique_id':'002', 'key1':'AAA', 'key2':'CCC', 'key3':'FFF'}]
>>> list_2 = [{'unique_id':'001', 'key1':'AAA', 'key2':'DDD', 'key3':'EEE'},
              {'unique_id':'002', 'key1':'AAA', 'key2':'CCC', 'key3':'FFF'}]
>>> pairs = Zip(list_1, list_2)
>>> any(x != y for x, y in pairs)
True

Ou pour obtenir les paires différentes:

>>> [(x, y) for x, y in pairs if x != y]
[({'key3': 'EEE', 'key2': 'BBB', 'key1': 'AAA', 'unique_id': '001'}, {'key3': 'EEE', 'key2': 'DDD', 'key1': 'AAA', 'unique_id': '001'})]

Vous pouvez même obtenir les clés qui ne correspondent pas pour chaque paire:

>>> [[k for k in x if x[k] != y[k]] for x, y in pairs if x != y]
[['key2']]

Peut-être avec les valeurs associées:

>>> [[(k, x[k], y[k]) for k in x if x[k] != y[k]] for x, y in pairs if x != y]
[[('key2', 'BBB', 'DDD')]]

NOTE: Si vos listes d'entrées ne sont pas encore triées, vous pouvez aussi le faire facilement:

>>> from operator import itemgetter
>>> list_1, list_2 = [sorted(l, key=itemgetter('unique_id')) 
                      for l in (list_1, list_2)]
28
Niklas B.

Le moyen le plus rapide et le plus complet serait d’utiliser deux sets de tuples:

set_list1 = set(Tuple(sorted(d.items())) for d in list1)
set_list2 = set(Tuple(sorted(d.items())) for d in list2)

Trouvez chevauchement en utilisant intersection:

set_overlapping = set_list1.intersection(set_list2)

Trouvez difference en utilisant symmetric_difference

set_difference = set_list1.symmetric_difference(set_list2)

Convertir Tuple retour à dict

 for Tuple_element in set_difference:
     list_dicts_difference.append(dict((x, y) for x, y in Tuple_element))
4
gies0r

J'ai une version qui ne dépend pas d'une clé particulière, donc les éléments sont égaux (zéro) ou non (non-zer):

list_1 = [{'unique_id':'001', 'key1':'AAA', 'key2':'BBB', 'key3':'EEE'}, {'unique_id':'002', 'key1':'AAA', 'key2':'CCC', 'key3':'FFF'}]
list_2 = [{'unique_id':'001', 'key1':'AAA', 'key2':'DDD', 'key3':'EEE'}, {'unique_id':'002', 'key1':'AAA', 'key2':'CCC', 'key3':'FFF'}]
list_3 = [{'Name': 'Abid', 'Age': 27},{'Name': 'Mahnaz', 'Age': 27}]
list_4 = [{'Name': 'Abid', 'Age': 27},{'Name': 'Mahnaz', 'Age': 27}]

print cmp(list_1,list_1)
print cmp(list_1,list_3)
print cmp(list_1,list_2)
print cmp(list_2,list_1)
print cmp(list_3,list_4)

donne:

Return Value :  0
Return Value :  1
Return Value : -1
Return Value :  1
Return Value :  0
1
alemol

Ce qui suit compare les dictionnaires et imprime les éléments non égaux:

for d1, d2 in Zip(list_1, list_2):
    for key, value in d1.items():
        if value != d2[key]:
            print key, value, d2[key]

Sortie: key2 BBB DDD. En utilisant Zip, nous pouvons parcourir deux dictionnaires à la fois. Nous parcourons ensuite les éléments du premier dictionnaire et comparons la valeur avec la valeur correspondante dans le deuxième dictionnaire. Si elles ne sont pas égales, nous imprimons la clé et les deux valeurs.

1
Simeon Visser
Let list1 = []
list2 = []

To fetch all the key values we can do like this:
key_values = list1[0]
key = key_values.keys() //key is a list and contains all key values

below is a piece of code which compares all the key pair values:

for val in list1:
    first_key = key[0]
    for val2 in list2:
        if val2[first_key] == val[first_key]:
            for val3 in key:
                if val2[val3] != val[val3]:
                    Unmatched.append(val)

print unmatched

Above contains matches dictionary and prints for which all key, pair values didn't match.
0
sushh
def new_change(old_list, new_list):
    change_list = []
    for x in new_list:
        for y in old_list:
            if x['unique_id'] != y['unique_id']:
                change_list.append(x)
    return change_list

passer l'ancienne et la nouvelle liste à côté de cette méthode

0
Aryan