2012-04-22 35 views
6

Tôi cần so sánh 2 từ điển để tìm tập hợp các khóa trong một từ điển không nằm trong từ điển kia.Cách ngắn gọn để tìm sự khác biệt "chính" giữa 2 từ điển?

Tôi biết rằng Python thiết đối tượng hỗ trợ:

set3=set1-set2 

nhưng tôi không thể làm:

dict3=dict1-dict2 

hay:

missingKeys=dict1.keys()-dict2.keys() 

(Tôi là một chút ngạc nhiên bởi điểm cuối cùng, bởi vì trong Java các khóa là một đối tượng Set.) Một giải pháp là:

missingKeys=set(dict1.keys())-set(dict2.keys()) 

có cách nào hay hơn hay ngắn gọn hơn để thực hiện việc này?

+0

Tôi nghĩ rằng dòng cuối cùng là đủ ngắn gọn bản thân mình, nhưng ... Tôi đoán một câu hỏi thú vị hơn "Làm thế nào để loại bỏ tất cả z trong Y từ X?" trong đó X và Y là các danh sách. Điều này sẽ hữu ích khi các bản sao z tồn tại trong X xuất hiện trong Y nên được để lại một mình, ví dụ. –

+0

@pst: Vâng, nó cảm thấy một chút kỳ lạ để tạo ra các đối tượng thiết lập, chỉ để tận dụng sự khác biệt() chức năng ... –

+0

Mặt khác, bởi vì nó * là * một bộ, nó có thể tận dụng một O tốt hơn ... cho sự khác biệt danh sách bằng cách sử dụng hiểu là dễ dàng, nhưng một chút tẻ nhạt hơn. Tuy nhiên, hiệu suất tương tự nếu danh sách "được thăm dò" được chuyển đổi thành 'tập'. –

Trả lời

3

lẽ

[x for x in dict1.keys() if x not in dict2.keys()] 
+2

Tôi nghĩ rằng điều này thậm chí có thể ngắn gọn hơn một chút: '[x cho x trong dict1.keys() nếu x không phải trong dict2]' vì 'x trong dict.keys()' là giống như 'x trong dict' – mgilson

+0

@mgilson: miễn là bạn chỉ ra 'x trong dict' là giống như' x trong dict.keys() ', thì giảm hoàn toàn là' [x cho x trong dict1 nếu x không phải trong dict2] '. –

+1

@SamGoldberg Bạn đúng.Lý do tôi không nghĩ về nó là vì 'for x in dict' gọi phương thức' __iter__' trên dict trong khi 'if x in dict' gọi phương thức' __contains__'. Vì vậy, trong trường hợp này, 'in' có hai thứ khác nhau - chúng chỉ xảy ra để có cùng kết quả. Dù sao: '[x cho x trong dict1 nếu x không phải trong dict2]' là ngắn gọn nhất như bạn đã chỉ ra. – mgilson

15

Python 2.7:

>>> d = {1:2, 2:3, 3:4} 
>>> d2 = {2:20, 3:30} 
>>> set(d)-set(d2) 
set([1]) 

Python 3.2:

>>> d = {1:2, 2:3, 3:4} 
>>> d2 = {2:20, 3:30} 
>>> d.keys()-d2.keys() 
{1} 
+0

+1 Ồ, lén lút Python 3.x! –

+0

Vì vậy, bạn đang nói rằng Python 3.2 dict.keys() phương thức trả về một tập hợp (như Java)? Bất kỳ lý do tại sao phiên bản trước đó đã không làm điều đó? –

+2

@SamGoldberg: không, nó thực sự trả về một đối tượng dict_keys, không phải là một tập hợp, nhưng nó có nhiều hoạt động giống như thiết lập. Xem, ví dụ: [câu hỏi này] (http://stackoverflow.com/questions/7296716/what-is-dict-keys-dict-items-and-dict-values). – DSM

4

Đối với cách cầm tay để làm việc đó tôi sẽ đề nghị sử dụng dict.viewkeys bằng Python 2.7 - nó là backport của Python 3.x dict.keys và được tự động chuyển đổi bằng 2to3.

Ví dụ:

>>> left = {1: 2, 2: 3, 3: 4} 
>>> right = {2: 20, 3:30} 
>>> left.viewkeys() - right.viewkeys() 
set([1]) 
1

này nên làm việc trong Python 2.7 và 3.x:

>>> keys = getattr(dict, 'viewkeys', dict.keys) 
>>> left = {1: 2, 2: 3, 3: 4} 
>>> right = {2: 20, 3:30} 
>>> list(keys(left) - keys(right)) 
[1] 
Các vấn đề liên quan