解包时 defaultdict 引发 KeyError
Posted
技术标签:
【中文标题】解包时 defaultdict 引发 KeyError【英文标题】:defaultdict raising KeyError when unpacked 【发布时间】:2020-12-20 15:56:22 【问题描述】:我在使用collections.defaultdict
和.format()
方法时得到了KeyError
Shell 执行
In [1]: from collections import defaultdict
In [2]: foo = "Foo: foo\nBar: bar"
In [3]: default = defaultdict(lambda: 0)
In [4]: foo.format(**default)
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-4-799cab129cf2> in <module>
----> 1 foo.format(**default)
KeyError: 'foo'
我不期待KeyError
,因为我使用的是defaultdict
。为什么会这样?
除此之外,我想用一些默认值填充foo
变量,我该怎么做?
【问题讨论】:
你到底想达到什么目的? 我希望这也在 OP 中。 “我想用一些默认值填充foo
变量”
顺便说一下,KeyError
不会因为defaultdict
而直接引发。如果你只是做foo.format()
你会得到完全相同的错误
是的,但是,defaultdict
不应该在我们寻找丢失的密钥时引发KeyError
,这就是defaultdict
的目的
是的,我想这与影子游侠的答案直接相关,在上面的代码中,format
试图做类似kwargs['foo']
的事情,其中kwargs
是空的,而format_map
会做default['foo']
并使用defaultdict
的力量
【参考方案1】:
使用**
进行解包会转换为真正的dict
(或功能上等效的不相关数据结构;实现细节丰富),因此defaultdict
的功能不会被使用。在这种情况下,您可以改为use str.format_map
,它接受(不解包)任意映射,而不将其强制为dict
。它正是为此目的而存在的(引用文档:“这很有用,例如 mapping
是一个 dict 子类”):
In [5]: foo.format_map(default)
Out[5]: 'Foo: 0\nBar: 0'
【讨论】:
它以什么方式转换为真正的dict
?我认为它只是解压缩为关键字参数。
@ArakkalAbu:是的,对于那些在 Python 2 天里学习 Python 的人来说,他们永远不会看到它(直到 3.2 才添加它)。通常不需要它,但您的用例是它有用的主要用例。
@superbrain 确实如此,但它只解包确实存在的密钥,因此在format
调用的另一端,所有 kwargs 都被打包回......一个普通的字典
@ShadowRanger 也适用于在 P2 时期学习 Python 的人,%
刚刚与 defaultdict
一起工作 OOTB。它仍然如此,但确实如此。
您是否有关于使用**
解包转换为真正的dict
的文档参考?以上是关于解包时 defaultdict 引发 KeyError的主要内容,如果未能解决你的问题,请参考以下文章
停止 Unix `tar` 命令在解包时创建完整目录路径 [关闭]