2012-06-21 145 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 
相关问题