解包时 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` 命令在解包时创建完整目录路径 [关闭]

defaultdict

python库整理:collections.defaultdict

理解 Python 语言中的 defaultdict

python中defaultdict方法的使用

R语言安装包时遇到arch - i386错误时解决方案