如何将列表作为字典的默认值? [复制]
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.defaultdict
和list
默认值:
from collections import defaultdict
dct = defaultdict(list)
然后只需使用:
dct[key].append(some_value)
如果键不在映射中,字典将为您创建一个新列表。 collections.defaultdict
是 dict
的子类,在其他方面的行为就像普通的 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。你救了一条命以上是关于如何将列表作为字典的默认值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章