2012-04-22 55 views
6

我需要比較2個字典來找到一個字典中不存在的字典集。簡明的方法來找到2個字典之間的「關鍵」區別?

我知道了Python 設置對象支持:

set3=set1-set2 

,但我不能這樣做:

dict3=dict1-dict2 

或:

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

(我有點驚訝最後一點,因爲在Java中,鍵是Set對象。)一種解決方案是:

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

有沒有更好或更簡潔的方法來做到這一點?

+0

我認爲最後一行充分凝練自己,但......我想一個更有趣的問題是「如何從X中刪除Y中的所有z?」 X和Y是列表。例如,當X中存在重複的z時,這應該是非常有用的。 – 2012-04-22 23:04:37

+0

@pst:那麼,創建設置對象有點奇怪,只是爲了利用差異()函數... – 2012-04-22 23:05:39

+0

另一方面,因爲它*是一個集合,它可以利用更好的O ...對於列表差異使用理解很容易,但稍微羅嗦一點。儘管如此,如果將「探測」列表轉換爲「集合」,仍然具有相同的性能。 – 2012-04-22 23:06:56

回答

3

也許

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

我想這可能會更簡潔一些:'[x for dict1.keys()if x without in dict2]''因爲dict.keys()中的x與dict中的x相同「 – mgilson 2012-04-22 23:38:44

+0

@mgilson:只要您指出'x in dict'與dict.keys()'中的'x相同,那麼完整的縮減是'[x for dict1 in xict in dict2]'。 – 2012-04-23 00:15:08

+1

@SamGoldberg你是對的。我沒有想到它的原因是因爲'for x in dict'在一個字典中調用'__iter__'方法,而'如果在dict中x'調用'__contains__'方法。因此,在這種情況下,'in'做了兩件不同的事情 - 它們恰好有相同的結果。無論如何:如果你指出,'[x for dict1 if x not in dict2]'是最簡潔的。 – mgilson 2012-04-23 00:54:22

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哦,鬼鬼祟祟的Python 3.x! – 2012-04-22 23:08:12

+0

所以你說Python 3.2 dict.keys()方法返回一個集合(如Java)?任何原因爲什麼早期版本不這樣做? – 2012-04-23 00:08:24

+2

@SamGoldberg:不,它實際上會返回一個dict_keys對象,而不是一個集合,但它有許多類似集合的操作。參見例如[這個問題](http://stackoverflow.com/questions/7296716/what-is-dict-keys-dict-items-and-dict-values)。 – DSM 2012-04-23 00:19:14

4

對於這樣做的可移植的方式,我建議在Python 2.7使用dict.viewkeys - 它是Python 3.x dict.keys的backport,並自動被2to3轉換。

例子:

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

這應該在Python 2.7的工作和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]