2012-10-10 56 views
1

可能重複:
How to raise error if duplicates keys in dictionary檢查字典一倍鍵

我最近產生巨大的詞典與成千上萬的鍵(例如,通過看他們WASN」注意到一個bug t可行)。它們在語法上是正確的,但在某處存在錯誤。它歸結爲「重複鍵」:

{'a':1, ..., 'a':2} 

這個代碼編譯好,我無法弄清楚,爲什麼a關鍵有2值如我所料1。現在這個問題很明顯。

問題是我如何能夠在將來防止這種情況。我認爲這在python中是不可能的。我用

grep "'.*'[ ]*:" myfile.py | sort | uniq -c | grep -v 1 

這是不是防彈。任何其他想法(在python中,這個grep只是爲了說明我試過的)?

編輯:我不想重複鍵,只需要找出出現這種情況,並手動

+0

是問題的重複鍵是在你的數據嗎?意思是你要他們標記(或重複忽略)。 –

+0

最簡單的方法是創建和使用dict的自定義子類(請參閱上述問題的鏈接),當您嘗試添加重複鍵時,它會失敗,並顯示錯誤消息。如果這真的是你想要的,你甚至可以修改行爲來忽略重複。 –

+1

現在我看到,事實上,這是一個愚蠢的問題,相關的答案解決了我的問題。我想知道爲什麼這樣的行爲(通知用戶他正在複製密鑰)在Python中不是默認行爲,我無法想象當雙倍密鑰值得期望時的情況。我應該關閉/刪除這個問題嗎? (如何?) – bartekbrak

回答

0

的字典不能包含雙鍵編輯數據。所以你所需要做的就是執行代碼,然後轉儲字典的repr()

另一個選項是創建字典項目爲(key, value)元組。通過將它們存儲在列表中,您可以輕鬆地從它們中創建一個字典,然後檢查字典/列表的len()是否有所不同。

+0

問題是,一個字典**可以包含雙鍵,就像我的問題所展示的那樣,但是它默默地重新分配了新的值。 'repr()'如何幫助我?請記住,字典是巨大的,我不能通過查看轉儲數據的MB來推斷任何東西。我發現你的答案的第二部分很有價值,雖然它降低了我的代碼的可讀性。謝謝 – bartekbrak

+0

它不會檢測到他們,但你可以創建一個新的字典沒有這些愚蠢。 – ThiefMaster

+0

@ user35186:Python字典**不能包含重複鍵。另一方面,[字典顯示](http://docs.python.org/reference/expressions.html#dictionary-displays)基本上是一個可用於構建字典的字符串表示形式,可以包含它們。這是你在你的問題中顯示的內容。您需要在正在創建的字典顯示中檢測重複項。 – martineau

0

如果您需要每個鍵具有多個值,則可以使用defaultdict將值存儲在列表中。

>>> from collections import defaultdict 
>>> data_dict = defaultdict(list) 
>>> data_dict['key'].append('value') 
>>> data_dict 
defaultdict(<type 'list'>, {'key': ['value']}) 
>>> data_dict['key'].append('second_value') 
>>> data_dict 
defaultdict(<type 'list'>, {'key': ['value', 'second_value']}) 
0

您是否正在生成包含巨型字典的Python文件?喜歡的東西:

print "{" 
for lines in file: 
    key, _, value = lines.partition(" ") 
    print " '%s': '%s'," 
print "}" 

如果是這樣,有沒有什麼可以做,以防止這一點,因爲你不能輕易覆蓋內置dict建設。

相反,我建議你在構造字典字符串時驗證數據。你也可以產生不同的語法:

dict(a = '1', a = '2') 

如果鑰匙被複制..這將產生一個SyntaxError。然而,這些並不完全相同,因爲字典鍵比關鍵字參數更靈活(例如{123: '...'} is valid, but dict(123 ='...')是錯誤的)

您可以生成如下函數調用:

uniq_dict([('a', '...'), ('a', '...')]) 

然後包括函數定義:

def uniq_dict(values): 
    thedict = {} 

    for k, v in values: 
     if k in thedict: 
      raise ValueError("Duplicate key %s" % k) 
     thedict[k] = v 

    return thedict 
0

你不說或顯示你究竟是如何產生的dictionary display您擁有的重複鍵出現。但這是問題所在。

而不是使用像{'a':1, ..., 'a':2}的東西來構建字典的,我建議你使用這種形式:dict([['a', 1], ..., ['a', 2]])這將從[key, value]雙所提供的列表中創建一個。這種方法將允許您檢查副本列表,然後將其傳遞到dict()以完成字典的實際構建。

這裏是一種方式的例子來檢查對重複項列表:

sample = [['a', 1], ['b', 2], ['c', 3], ['a', 2]] 

def validate(pairs): 
    # check for duplicate key names and raise an exception if any are found 
    dups = [] 
    seen = set() 
    for key_name,val in pairs: 
     if key_name in seen: 
      dups.append(key_name) 
     else: 
      seen.add(key_name) 
    if dups: 
     raise ValueError('Duplicate key names encountered: %r' % sorted(dups)) 
    else: 
     return pairs 

my_dict = dict(validate(sample))