在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
作为defaultdict
的default_factory
属性进行了讨论作为documentation的示例。
使用collections.defaultdict:
import collections
likes = collections.defaultdict(list)
for key, value in favorites.items():
likes[key].append(value)
defaultdict
需要一个参数,一个工厂点播未知键创造价值。 list
是一个这样的函数,它创建空的列表。
并且迭代.items()将使您无法使用该键来获取该值。
使用.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年以来。
啊,很好。 defaultdict在这里似乎是“正确”的解决方案,但这是一个很酷的选择。 – 2009-10-12 09:14:12
请注意,http://docs.python.org/3.1/library/collections.html#defaultdict-examples中的第一个示例明确指出,使用'defaultdict'比使用'setdefault'方法快。 – Stephan202 2009-10-12 09:15:52
也很高兴知道。谢谢斯蒂芬。 – 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()
是答案。
你们认为什么?
2.5及更高版本,或者您必须定义您自己的defaultdict类。 – 2009-12-11 07:28:57