2010-08-04 136 views
3

一個字典python dict通過鍵值去除重複值?

dic = { 
1: 'a', 
2: 'a', 
3: 'b', 
4: 'a', 
5: 'c', 
6: 'd', 
7: 'd', 
8: 'a', 
9: 'a'} 

我想刪除重複的值只是保持一個K/V對, 關於「鍵」選擇那些重複值的,其可以是最大或最小或通過隨機選擇其中的一個重複項目的關鍵。

我不想使用k/v交換,因爲它無法控制密鑰選擇。

採取值 「a」,例如

1: 'a', 
2: 'a', 
4: 'a', 
8: 'a', 
9: 'a' 

最大關鍵將是{9: 'A'}和最小將是{1: 'A'},以及隨機會的choise任一項的。

而且,如果關鍵字是其他類型的可哈希值,例如string,那麼如何做這樣的選擇?

任何人都可以分享我的想法嗎?

謝謝!

+0

你可以翻轉它,讓鍵是值,反之亦然? – sas4740 2010-08-04 03:25:21

+0

OP確實說過「我不想使用ak/v swap,因爲它無法控制密鑰選擇」 - 模糊,但我認爲這意味着值可能是列表,字典或其他不可接受的對象作爲關鍵。 – 2010-08-04 05:29:32

回答

2
import itertools as it 

newdic = {} 
for v, grp in it.groupby(sorted((v, k) for k, v in dic.items)): 
    newdic[min(k for _, k in grp)] = v 

或其他「選擇」,以代替min功能(其中,當然,也做工精細,即使鍵是字符串 - 會給你在這種情況下,「詞彙第一」鍵)。

選擇函數需要注意的一種情況是,對應於相同值的鍵可能是不可比較的(例如,複數,或者在Python 3中,不同非全部數字類型的對象)。 min中的key=不會治癒;-)。

+0

謝謝亞歷克斯,我仍然在試圖找出如何隨機選擇重複的密鑰在你的方式。 – 2010-08-04 09:14:46

+0

@KC,'random.choice(list(grp))[1]'是最簡單的(當然有算法具有更好的big-O用於此目的,但除非您的重複密鑰組成長成多個每個鍵的數千個案例;-)。 – 2010-08-04 16:48:32

1

這會給你一個隨機選擇的唯一密鑰:

In [29]: dic 
Out[29]: {1: 'a', 2: 'a', 3: 'b', 4: 'a', 5: 'c', 6: 'd', 7: 'd', 8: 'a', 9: 'a'} 

In [30]: dict((v,k) for k,v in dic.iteritems()) 
Out[30]: {'a': 9, 'b': 3, 'c': 5, 'd': 7} 

In [31]: dict((v,k) for k,v in dict((v,k) for k,v in dic.iteritems()).iteritems()) 
Out[31]: {3: 'b', 5: 'c', 7: 'd', 9: 'a'} 
+1

你能解釋一下它爲什麼i​​teritem隨機返回 – 2010-08-04 04:06:55

+0

@註冊:Python的字典是無序的。因此,從dic.iteritems()發出鍵值對的順序是未確定的。我應該說「未定」而不是「隨機」。 – unutbu 2010-08-04 10:58:28

+0

@Registered:我錯過了一個事實,即您請求的方法不使用鍵值交換。對不起 - 這正是我上面做的。我會留下來讓你閱讀,然後在一天左右刪除。 – unutbu 2010-08-04 11:04:42

5

你可以建立一個反向字典,其中值是從初始字典中所有鍵的列表。使用這個,你可以做你想要的,min,max,random,alternate min和max,或者其他。

from collections import defaultdict 

d = defaultdict(list) 
for k,v in dic.iteritems(): 
    d[v].append(k) 

print d 
# {'a': [1, 2, 4, 8, 9], 'c': [5], 'b': [3], 'd': [6, 7]} 
+0

很容易理解那些值可哈希,謝謝! – 2010-08-04 09:23:16