在不同来源的词典中编译数据时,这是一种常见情况:
假设您有一个存储事物列表的字典,例如我喜欢的事物:
likes = {
'colors': ['blue','red','purple'],
'foods': ['apples', 'oranges']
}
和第二个包含一些相关值的字典:
favorites = {
'colors':'yellow',
'desserts':'ice cream'
}
然后,您想迭代“favorites”对象,并使用“likes”字典中的相应键将该对象中的项目附加到列表中,或者向其添加一个新键,其值为包含该列表的列表“收藏夹”中的价值。
有几种方法可以做到这一点:
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])
还有更多......
我通常使用第一种语法,因为它感觉更加pythonic,但如果还有其他更好的方法,我很想知道它们是什么。谢谢!
答案 0 :(得分:5)
使用collections.defaultdict
,默认值为新的list
实例。
>>> import collections
>>> mydict = collections.defaultdict(list)
这样调用.append(...)
将始终成功,因为如果存在不存在的键append
,则会在新的空列表中调用。
您可以使用之前生成的列表来实例化defaultdict
,以防您从其他来源获取dict likes
,如下所示:
>>> mydict = collections.defaultdict(list, likes)
请注意,使用list
作为default_factory
的{{1}}属性也会在documentation中作为示例进行讨论。
答案 1 :(得分:3)
使用collections.defaultdict:
import collections
likes = collections.defaultdict(list)
for key, value in favorites.items():
likes[key].append(value)
defaultdict
只接受一个参数,一个工厂,可根据需要为未知密钥创建值。 list
是一个这样的函数,它会创建空列表。
迭代.items()将使您无法使用密钥获取值。
答案 2 :(得分:2)
除了defaultdict,常规字典提供了一种可能性(可能看起来有点奇怪):dict.setdefault(k[, d])
:
for key, val in favorites.iteritems():
likes.setdefault(key, []).append(val)
感谢你代表+20 - 我从1989年到2009年30秒。让我们记住,自从沃尔在欧洲倒台已有20年了。
答案 3 :(得分:1)
>>> 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']})
答案 4 :(得分:1)
所有答案都是defaultdict
,但我不确定这是最好的解决方法。将defaultdict
发给需要dict的代码可能会很糟糕。 (参见:How do I make a defaultdict safe for unexpecting clients?)我个人对此事表示不满。 (我实际上发现这个问题正在寻找“哪个更好,dict.get()
或defaultdict
”的答案。另一个帖子中有人说如果你不穿defaultdict
你就不想要defaultdict(list)
一直不想要这种行为,这可能是真的。为方便起见,使用defaultdict可能是错误的方法。我认为这里有两个需要混淆:
“我想要一个默认值为空列表的dict。” my_dict.get('foo', [])
是正确的解决方案。
和
“如果该密钥存在,我想附加到该密钥列表中,如果该密钥不存在则创建一个列表。” append()
{{1}}就是答案。
你们有什么想法?