2015-07-13 59 views
5

我正在尋找交換給定字典的所有鍵值對的方法。在字典中交換鍵值對

到目前爲止,我能想到的一種方式做它:

例:

>>>a = { 0: 'a', 1 : 'b', 2 : 'c' } 
>>> {value : key for key,value in a.items()} 
{'a': 0, 'b': 1, 'c' : 2} 

但爲了這個,我將不得不使用額外的空間來聲明另一個字典。
我想知道我可以使用哪些方法將鍵值對交換更多的空間效率。

+4

如果兩個值重複或者您有一個不可哈希值? –

+0

@PadraicCunningham那麼,如果兩個(或更多)鍵具有相同的值,那麼覆蓋將是唯一的方法。我猜 ! –

+0

@PadraicCunningham我沒有想過這個難以置信的價值場景!任何建議將有助於 –

回答

3

但爲此,我將不得不使用額外的空間來聲明另一個字典。

由於字典本質上是一個查找表,因此它有一種具體的方式將其放在內存中;密鑰被有效地分配,並且指向它們本身沒有特殊含義的值。因此,當你想要反轉映射時,你不能真正使用現有的結構;相反,您將不得不從頭開始創建新的字典條目。你在你的問題中使用的字典理解是一個很好和明確的方法來做到這一點。

什麼你可能但是做的是重新使用字典你已經擁有並添加新鍵有(同時去除舊的):

for k in a: 
    a[a[k]] = k 
    del a[k] 

這會修改同一個字典,所以它贏得」不會有新詞典的(可能很少)開銷。請注意,這假定所有值都是唯一的,因此映射可以完全相反,並且鍵和值集不共享公共值。否則,您將遇到字典大小更改的異常或缺失的值。您可以通過創建字典密鑰的副本避免前(雖然這意味着你有一個列表存儲現在太):

for k in list(a): 
    if a[k] != k: 
     a[a[k]] = k 
     del a[k] 

最後請注意:這有可能是字典多次修改這樣的威力雖然有一些重新映射的副作用(增加散列表大小等),但這是CPython的可能實現細節(我不太確定它)。

+1

正如所寫的,這不會(1)給出字典改變大小的錯誤,並且(2)在某些情況下不起作用,例如, 'a = {1:1,2:3,3:2}'? – DSM

+0

@DSM是的,這可能是可能的,儘管它用OP的例子爲我工作。您可能必須創建密鑰列表的副本。至於(2),是的,對於這個例子它會中斷,但我假設的情況類似於OP的例子,其中鍵集和值集是不同的。 – poke

0

試試看看這個代碼。在反轉鍵和值之前,它會刪除字典中的項目。

for k, v in a.items(): 
    del a[k] 
    a[v] = k 
0

爲避免覆蓋@DSM在@ poke的答案中指出的特殊情況,我建議您始終使用第二個字典。性能是相同的。

b = dict() 
for k, v in a.items(): # a.iteritems() in python 2 
    b[v] = k 
    del a[k] 
a = b