2012-06-21 192 views
2

有什麼方法可以將重複密鑰存儲在字典中?有沒有辦法在Python字典中保留重複密鑰

我有一個具體的要求,形成對請求和響應。從一個特定的節點

請求到另一個特定的節點形式相同的密鑰。我需要存儲這兩個。

但是,如果我試圖將它們添加到字典中,第一個是由第二所取代。有什麼辦法嗎?

+7

難道一個*字典*定義*不*允許重複鍵? – Levon

+0

只要我看到單詞「節點」 - 我想'圖'。你能否進一步評論你的最終目標,而不是你覺得你可能擁有的實現問題 –

回答

8

我可以想到兩個簡單的選項,假設你想繼續使用字典。

  1. 您可以將鍵映射到項目列表。來自collections模塊的defaultdict使這一切變得簡單。

    >>> import collections 
    >>> data = collections.defaultdict(list) 
    >>> for k, v in (('a', 'b'), ('a', 'c'), ('b', 'c')): 
    ...  data[k].append(v) 
    ... 
    >>> data 
    defaultdict(<type 'list'>, {'a': ['b', 'c'], 'b': ['c']}) 
    
  2. 你可以使用額外的數據來澄清對鍵。這可能是一個時間戳,一個唯一的ID號碼或其他東西。這具有保留鍵和值之間的一對一關係的優點,以及使查找更復雜的缺點,因爲您始終必須指定id。下面的例子顯示了這可能如何工作;無論是對你有好處取決於問題域:

    >>> for k, v in (('a', 'b'), ('a', 'c'), ('b', 'c')): 
    ...  i = 0 
    ...  while (k, i) in data: 
    ...   i += 1 
    ...  data[(k, i)] = v 
    ... 
    >>> data 
    {('a', 1): 'c', ('b', 0): 'c', ('a', 0): 'b'} 
    
4

有沒有辦法做到這一點,沒有。字典依賴於唯一的密鑰 - 否則,當您請求或設置密鑰時,將返回或覆蓋哪些值?

你可以做什麼,但是,是存儲列表作爲字典的值,然後添加你的價值觀到列表中,而不是替換現有的值。

你可能想使用一個collections.defaultdict要做到這一點,要避免用手一個新的關鍵是引入每次列表。

+0

這個詞典的關鍵是什麼? – newbie555

+0

好吧,我明白了......我可以使用count作爲詞典的關鍵字,併爲每個列表添加值作爲下一個條目,我可以增加計數。 – newbie555

+0

@rockluke你所描述的是一個列表,而不是一本字典。如果你的鑰匙有問題,那麼列表更適合。 –

8

雖然我不是100%肯定,我敢肯定的答案是否定的。這種違反Python中字典的目的。你怎麼樣的值更改爲列表,以便代替

{Key:value} 

你有

{Key:[Value1,value2]} 
3

使用列表來存儲所有的值相等的鍵:

{a:b, a:c} # foolish, won't work 
{a: [ b, c ]} # works like a charm! 

您可能還需要使用

from collections import defaultdict 
d = defaultdict(list) 
d[a].append(b) 

以簡單的方式填寫你的字典。

+0

好吧,我明白了......我可以使用count作爲字典的關鍵字,併爲每個列表添加值作爲值,對於下一個條目,我可以增加計數。 – newbie555

0

根據定義,字典要求密鑰是唯一標識符。你可以:

  1. 使用不同的數據結構,如允許重複條目的列表或元組。
  2. 使用字典密鑰的唯一標識符,這與數據庫可能使用自動遞增字段作爲其密鑰ID的方式非常相似。

如果你正在存儲大量的請求/響應對,那麼無論如何你最好還是使用數據庫。這當然值得考慮。

5

defaultdict另一種可能是

d = {} 
d.setdefault(newkey, []).append(newvalue) 

這確實是相同的:追加newvalue到這是不是已經在給定的newkey,或者如果不是字典,將被放在那裏的列表。

1

我喜歡用collections.defaultdict的答案。這就是我可能會去的方式。

但是,假設一個字典或類字體結構和一對多映射是正確的解決方案。重讀這個問題,「形成請求和響應對」的要求可能會導致更簡單的元組列表(或列表列表)方法。例如: -

pairs = [] 
pairs.append((request, response)) 

這可能會創建這樣一個列表:

[ ('GET /', 200), ('GET /index.html', 200), ('GET /x', 403), ('GET /', 200), ] 

這只是輕微的結構,但是這取決於你想用它做什麼,可能是罰款。

0

一個更優雅的解決方案:

def add_to_dict(towhat, key, value): 
    info = towhat.get(key, []) 
    info.append(value) 
    towhat[key] = info 

alternate = {} 

add_to_dict(alternate,"Andrew","Cambridge") 
add_to_dict(alternate,"Barbara","Bloomsbury") 
add_to_dict(alternate,"Andrew","Corsica") 

print alternate 
相關問題