2012-03-23 12 views
15

Ho 2 elenchi, che contengono entrambi lo stesso numero di dizionari. Ogni dizionario ha una chiave univoca. Esiste una corrispondenza per ogni dizionario del primo elenco nel secondo elenco, ovvero un dizionario con una chiave univoca presente nell'altro elenco. Ma gli altri elementi di questi 2 dizionari possono variare. Per esempio:Confronto di 2 elenchi composti da dizionari con chiavi univoche in python

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

voglio mettere a confronto tutti gli elementi del 2 dizionari di corrispondenza. Se uno qualsiasi degli elementi non è uguale, voglio stampare gli elementi non uguali.

La prego quindi di aiutare,

Grazie Saluti

risposta

21

Supponendo che il dicts allineano come nel vostro ingresso esempio, è possibile utilizzare la funzione zip() per ottenere una lista di coppie associate di dicts, poi è possibile utilizzare any() per verificare se c'è una differenza:

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

O per ottenere le coppie diverse:

>>> [(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'})] 

È possibile anche ottenere le chiavi che non corrispondono per ogni coppia:

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

Possibilmente insieme ai valori associati:

>>> [[(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')]] 

NOTA: Nel caso siate gli elenchi di input non sono ancora ordinati, lo puoi fare facilmente:

>>> from operator import itemgetter 
>>> list_1, list_2 = [sorted(l, key=itemgetter('unique_id')) 
         for l in (list_1, list_2)] 
+0

@Lattyware: Sì, presumo che gli elenchi siano allineati in modo che i dicts corrispondenti abbiano la stessa posizione in entrambi gli elenchi. Mi è sembrato che questa fosse la situazione che l'OP affronta. –

+0

@ Niklas.B.Definitamente, ma ho pensato di parlarne per completezza. –

+0

@Niklas B .: Sì, gli elenchi sono ordinati. Ma potrebbe non essere stato. Come lo farei se le liste non fossero ordinate? – alwbtc

1

Di seguito confronta i dizionari e la stampa dei componenti non-uguali:

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

uscita: key2 BBB DDD. Usando zip possiamo scorrere su due dizionari alla volta. Successivamente, iteriamo sugli elementi del primo dizionario e confrontiamo il valore con il valore corrispondente nel secondo dizionario. Se questi non sono uguali, stampiamo la chiave e entrambi i valori.

+0

come fa a sapere che dovrebbe confrontare dizionari con la stessa chiave "unique_id"? – alwbtc

+1

Sulla base dell'esempio ho assunto la lista con i dizionari è stato ordinato. Se questo non è il caso, devi prima ordinarlo con 'unique_id'. –

1

Ho una versione che in realtà non fa dipende da una chiave particolare, quindi gli elementi sono uguali (zero) o non sono (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) 

dà:

Return Value : 0 
Return Value : 1 
Return Value : -1 
Return Value : 1 
Return Value : 0 
lista
+0

cosa fa '' 'cmp()' '' do? mi puoi fornire l'implementazione di '' 'cmp()' '' –

+0

@ShubhamSrivastava: si può leggere dalla informazione ufficiale "cmp (x, y) confrontare i due oggetti x e y e restituire un intero secondo il esito. Il valore restituito è negativo se x y". https://docs.python.org/2/library/functions.html#cmp – alemol

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

passaggio vecchio e nuovo in parte di questo metodo

Problemi correlati