在Python迭代期间添加新键或追加到字典中旧键的最有效方法?
这是在不同来源的字典中编译数据时的常见情况:
假设您有一个存储事物列表的字典,例如我喜欢的事物:
likes = {
'colors': ['blue','red','purple'],
'foods': ['apples', 'oranges']
}
以及第二个字典,其中包含一些相关值:
favorites = {
'colors':'yellow',
'desserts':'ice cream'
}
然后您想要迭代“收藏夹” “对象,并使用“喜欢”字典中的适当键将该对象中的项目附加到列表中,或者向其添加一个新键,其值是包含“收藏夹”中的值的列表。
有几种方法可以做到这一点:
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,但如果有其他更好的方法,我很想知道它们是什么。谢谢!
Here's a common situation when compiling data in dictionaries from different sources:
Say you have a dictionary that stores lists of things, such as things I like:
likes = {
'colors': ['blue','red','purple'],
'foods': ['apples', 'oranges']
}
and a second dictionary with some related values in it:
favorites = {
'colors':'yellow',
'desserts':'ice cream'
}
You then want to iterate over the "favorites" object and either append the items in that object to the list with the appropriate key in the "likes" dictionary or add a new key to it with the value being a list containing the value in "favorites".
There are several ways to do this:
for key in favorites:
if key in likes:
likes[key].append(favorites[key])
else:
likes[key] = list(favorites[key])
or
for key in favorites:
try:
likes[key].append(favorites[key])
except KeyError:
likes[key] = list(favorites[key])
And many more as well...
I generally use the first syntax because it feels more pythonic, but if there are other, better ways, I'd love to know what they are. Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
使用
collections.defaultdict
,其中默认值是一个新的list
实例。通过这种方式,调用
.append(...)
将始终成功,因为如果键不存在,append
将在新的空列表上调用。您可以使用之前生成的列表实例化
defaultdict
,以防您从其他来源获取字典likes
,如下所示:请注意,使用
list
因为defaultdict
的default_factory
属性也在 文档。Use
collections.defaultdict
, where the default value is a newlist
instance.In this way calling
.append(...)
will always succeed, because in case of a non-existing keyappend
will be called on a fresh empty list.You can instantiate the
defaultdict
with a previously generated list, in case you get the dictlikes
from another source, like so:Note that using
list
as thedefault_factory
attribute of adefaultdict
is also discussed as an example in the documentation.使用 collections.defaultdict:
defaultdict 采用单个参数,即一个用于根据需要为未知键创建值的工厂。
list
就是这样一个函数,它创建空列表。迭代 .items() 将使您免于使用键来获取值。
Use collections.defaultdict:
defaultdict
takes a single argument, a factory for creating values for unknown keys on demand.list
is a such a function, it creates empty lists.And iterating over .items() will save you from using the key to get the value.
除了 defaultdict 之外,常规 dict 还提供了一种可能性(可能看起来有点奇怪):
dict.setdefault(k[, d])
:谢谢您的 +20 代表 - 我从 1989 年开始30 秒后到 2009 年。让我们记住,欧洲柏林墙倒塌已有 20 年了。
Except defaultdict, the regular dict offers one possibility (that might look a bit strange):
dict.setdefault(k[, d])
:Thank you for the +20 in rep -- I went from 1989 to 2009 in 30 seconds. Let's remember it is 20 years since the Wall fell in Europe..
所有答案都是
defaultdict
,但我不确定这是最好的方法。向需要字典的代码提供defaultdict
可能会很糟糕。 (请参阅:如何使 defaultdict 对于意外情况安全客户?)我个人对这个问题感到左右为难。 (我实际上发现这个问题正在寻找“哪个更好,dict.get()
”或“defaultdict
”的答案)另一个线程中的某人说你不如果您不希望一直出现这种行为,则需要一个defaultdict
,这可能是正确的。也许为了方便而使用 defaultdict 是错误的方法。我认为这里有两个需求被混为一谈:“我想要一个默认值为空列表的字典。”其中
defaultdict(list)
是正确的解决方案。和
“如果存在,我想将其追加到该键的列表中,如果不存在,则创建一个列表。”答案是
my_dict.get('foo', [])
和append()
。你们觉得怎么样?
All of the answers are
defaultdict
, but I'm not sure that's the best way to go about it. Giving outdefaultdict
to code that expects a dict can be bad. (See: How do I make a defaultdict safe for unexpecting clients? ) I'm personally torn on the matter. (I actually found this question looking for an answer to "which is better,dict.get()
ordefaultdict
") Someone in the other thread said that you don't want adefaultdict
if you don't want this behavior all the time, and that might be true. Maybe using defaultdict for the convenience is the wrong way to go about it. I think there are two needs being conflated here:"I want a dict whose default values are empty lists." to which
defaultdict(list)
is the correct solution.and
"I want to append to the list at this key if it exists and create a list if it does not exist." to which
my_dict.get('foo', [])
withappend()
is the answer.What do you guys think?