如何将列表作为字典的默认值? [复制]

Posted

技术标签:

【中文标题】如何将列表作为字典的默认值? [复制]【英文标题】:How to make a list as the default value for a dictionary? [duplicate] 【发布时间】:2013-07-19 07:46:27 【问题描述】:

我的 Python 代码如下所示:

if key in dict:
  dict[key].append(some_value)
else:
  dict[key] = [some_value]

但我认为应该有一些方法可以绕过这个“if”语句。我试过了:

dict.setdefault(key, [])
dict[key].append(some_value)

dict[key] = dict.get(key, []).append(some_value)

但两者都抱怨“TypeError: unhashable type: 'list'”。有什么建议吗?

【问题讨论】:

看起来您可能在使用列表键时遇到问题,与整个默认值无关。那,或者您不小心在实际代码中切换了一些参数,而您在将其发布到 SO 时没有这样做。 您的异常与您在此处发布的代码无关。这表明 key 是一个列表对象,它不是可散列的,因此不允许作为字典键。 除了 Martijn 对设置默认值的回答之外,您还遇到了使用 python 类名作为变量名的问题。当你说dict.setdefault(key, []) 时,你实际上是在调用'dict' 类对象上的未绑定的setdefault 方法。它将“key”视为自身指针并尝试使用“[]”作为索引。只需创建您自己的变量mydict = dict(),您就会走得更远。 @tdelaney:从帖子的其余部分,我推测 OP 在某些时候已经完成了dict = 。一个坏主意,因为它 masks 内置。如果dict 仍然是内置的,则例外情况完全不同:TypeError: descriptor 'setdefault' requires a 'dict' object but received a 'str'(对于key 中的str 值)。 哦,哇。我犯了大错。我没有意识到我通过写dict = 掩盖了一个内置函数。我的错。谢谢! 【参考方案1】:

最好的方法是使用collections.defaultdictlist 默认值:

from collections import defaultdict
dct = defaultdict(list)

然后只需使用:

dct[key].append(some_value)

如果键不在映射中,字典将为您创建一个新列表。 collections.defaultdictdict 的子类,在其他方面的行为就像普通的 dict 对象一样。

当使用标准的dict 时,dict.setdefault() 正确地为您将dct[key] 设置为默认值,因此该版本应该可以正常工作。您可以使用.append() 链接该调用:

>>> dct = 
>>> dct.setdefault('foo', []).append('bar')  # returns None!
>>> dct
'foo': ['bar']

但是,通过使用dct[key] = dct.get(...).append(),您替换dct[key] 的值与.append() 的输出,即None

【讨论】:

这个解决方案将我的执行时间从 2 小时缩短到 15 分钟。我有非常大的字典,当它们达到 3000 万个条目时,由于所有检查密钥是否已经存在,它们会减慢速度。同样值得注意的是,我使用的是 networkx 图,但内存开销很荒谬。现在使用默认字典,在 RAM 中加载 180GB 的相同图形现在使用默认字典需要不到 20GB。你救了一条命

以上是关于如何将列表作为字典的默认值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

DDMathParser:如何定义变量的默认值

空字典作为 dict.get() 的默认值

将列表对象作为函数参数传递(而不是默认值),是否有任何陷阱?

python函数使用参数技巧笔记

使用支持对象/结构的泛型时如何返回空值/默认值? [复制]

将默认dict更改为嵌套字典