2012-03-23 35 views
15

Tôi có 2 danh sách, cả hai đều chứa cùng một số từ điển. Mỗi từ điển có một khóa duy nhất. Có một kết quả phù hợp cho từng từ điển trong danh sách thứ hai trong danh sách thứ hai, đó là một từ điển có khóa duy nhất tồn tại trong danh sách khác. Nhưng các yếu tố khác của 2 từ điển này có thể khác nhau. Ví dụ:So sánh 2 danh sách bao gồm từ điển với các khóa duy nhất trong 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' 
      } 
     ] 

Tôi muốn so sánh tất cả các phần tử của 2 từ điển phù hợp. Nếu bất kỳ phần tử nào không bằng nhau, tôi muốn in các phần tử không bằng nhau.

Xin giúp đỡ,

Cảm ơn Trân trọng

Trả lời

21

Giả sử rằng các dicts xếp hàng như trong ví dụ đầu vào của bạn, bạn có thể sử dụng zip() chức năng để có được một danh sách các cặp liên quan của dicts, sau đó bạn có thể sử dụng any() để kiểm tra xem có sự khác biệt:

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

Hoặc để có được các cặp khác nhau:

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

Bạn thậm chí có thể nhận được các phím mà không phù hợp đối với từng cặp:

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

Có thể cùng với các giá trị liên quan đến:

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

LƯU Ý: Trong trường hợp bạn danh sách đầu vào chưa được sắp xếp, bạn cũng có thể làm điều đó dễ dàng:

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

@Lattyware: Có, tôi giả định rằng các danh sách được căn chỉnh theo cách mà các dicts trùng khớp có cùng vị trí trong cả hai danh sách. Dường như với tôi rằng đây là tình huống mà OP phải đối mặt. –

+0

@ NiklasB.Definitely, nhưng nghĩ rằng tôi muốn đề cập đến nó vì lợi ích đầy đủ. –

+0

@Niklas B .: Có, danh sách được sắp xếp. Nhưng nó có thể không có được. Làm thế nào tôi sẽ làm điều đó nếu các danh sách không được sắp xếp? – alwbtc

1

Sau đây so sánh các từ điển và in các mặt hàng phi bình đẳng:

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

Output: key2 BBB DDD. Bằng cách sử dụng zip, chúng tôi có thể lặp qua hai từ điển cùng một lúc. Sau đó chúng tôi lặp qua các mục của từ điển đầu tiên và so sánh giá trị với giá trị tương ứng trong từ điển thứ hai. Nếu chúng không bằng nhau, thì chúng ta sẽ in ra khóa và cả hai giá trị.

+0

Làm cách nào để biết rằng nó nên so sánh các từ điển với cùng một khóa "unique_id"? – alwbtc

+1

Dựa trên ví dụ tôi giả định danh sách có từ điển đã được đặt hàng. Nếu đó không phải là trường hợp thì bạn cần phải đặt nó trước tiên bởi 'unique_id'. –

1

Tôi có một phiên bản mà thực sự không phụ thuộc vào một phím đặc biệt, vì vậy các yếu tố đều bình đẳng (zero) hoặc họ không (không 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) 

cho:

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

'' 'cmp()' '' làm gì? bạn có thể cung cấp cho tôi việc thực hiện '' 'cmp()' '' –

+0

@ShubhamSrivastava: bạn có thể đọc nó từ thông tin chính thức "cmp (x, y) So sánh hai đối tượng x và y và trả về một số nguyên theo Giá trị trả về là âm nếu 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 

đường chuyền cũ và mới danh sách ở bên của phương pháp này

Các vấn đề liên quan