在Python迭代过程中添加新密钥或附加到字典中旧密钥的最有效方法?

问题描述:

不同来源的字典编纂的数据时,这是一个常见的情况:在Python迭代过程中添加新密钥或附加到字典中旧密钥的最有效方法?

假设你有一个存储的东西列出,比如事情的字典,我喜欢:

likes = { 
    'colors': ['blue','red','purple'], 
    'foods': ['apples', 'oranges'] 
} 

,并与一些相关的第二词典值是:

favorites = { 
    'colors':'yellow', 
    'desserts':'ice cream' 
} 

然后你要遍历“收藏夹”对象,无论是在该对象的项目进行适当的键追加到列表中的“喜欢”字典或添加新科y,它的值是一个包含“收藏夹”中的值的列表。

有几种方法可以做到这一点:

for key in favorites: 
    if key in likes: 
     likes[key].append(favorites[key]) 
    else: 
     likes[key] = list(favorites[key]) 

for key in favorites: 
    try: 
     likes[key].append(favorites[key]) 
    except KeyError: 
     likes[key] = list(favorites[key]) 

还有更多,以及...

我一般用第一种语法,因为它感觉更Python ,但如果还有其他更好的方法,我很想知道它们是什么。谢谢!

使用collections.defaultdict,其中默认值是一个新的list实例。

>>> import collections 
>>> mydict = collections.defaultdict(list) 

这样调用.append(...)将始终成功,因为在的情况下,不存在的关键append将一个新的空列表上调用。

您可以实例化defaultdict先前生成的列表,如果你从其他来源获得的字典likes,就像这样:

>>> mydict = collections.defaultdict(list, likes) 

注意,使用list作为defaultdictdefault_factory属性进行了讨论作为documentation的示例。

+0

2.5及更高版本,或者您必须定义您自己的defaultdict类。 – 2009-12-11 07:28:57

使用collections.defaultdict:

import collections 

likes = collections.defaultdict(list) 

for key, value in favorites.items(): 
    likes[key].append(value) 

defaultdict需要一个参数,一个工厂点播未知键创造价值。 list是一个这样的函数,它创建空的列表。

并且迭代.items()将使您无法使用该键来获取该值。

+0

使用.items()的好提示。这是我喜欢Python的东西之一。总有一种更好,更快,更智能的方式。 – 2009-10-12 09:21:45

>>> from collections import defaultdict 
>>> d = defaultdict(list, likes) 
>>> d 
defaultdict(<class 'list'>, {'colors': ['blue', 'red', 'purple'], 'foods': ['apples', 'oranges']}) 
>>> for i, j in favorites.items(): 
    d[i].append(j) 

>>> d 
defaultdict(<class 'list'>, {'desserts': ['ice cream'], 'colors': ['blue', 'red', 'purple', 'yellow'], 'foods': ['apples', 'oranges']}) 

除了defaultdict,常规字典提供了一种可能性(即可能看起来有点怪):dict.setdefault(k[, d])

for key, val in favorites.iteritems(): 
    likes.setdefault(key, []).append(val) 

感谢您代表的+20 - 我从1989年就到2009年在30秒内。让我们记住,自从欧洲墙倒塌20年以来。

+0

啊,很好。 defaultdict在这里似乎是“正确”的解决方案,但这是一个很酷的选择。 – 2009-10-12 09:14:12

+2

请注意,http://docs.python.org/3.1/library/collections.html#defaultdict-examples中的第一个示例明确指出,使用'defaultdict'比使用'setdefault'方法快。 – Stephan202 2009-10-12 09:15:52

+0

也很高兴知道。谢谢斯蒂芬。 – 2009-10-12 09:19:38

所有的答案是defaultdict,但我不确定这是最好的方式去做。给出defaultdict代码,预计字典可能是坏的。 (请参阅:How do I make a defaultdict safe for unexpecting clients?)我个人对这个问题非常感兴趣。 (我实际上发现这个问题寻找答案“哪个更好,dict.get()defaultdict”)另一个线程中的某个人表示,如果您不需要这种行为,那么您不需要defaultdict,那可能会是真实的。也许为了方便使用defaultdict是错误的方法。我认为这里有两个需要合并:

“我想要一个默认值为空列表的字典。” defaultdict(list)是正确的解决方案。

“我想在这个关键追加到列表中,如果它存在,如果不存在则创建一个列表。” my_dict.get('foo', [])append()是答案。

你们认为什么?