繁体   English   中英

Python defaultdict(default) vs dict.get(key, default)

[英]Python defaultdict(default) vs dict.get(key, default)

假设我想创建一个dict (或类似dict的对象),如果我尝试访问不在dict中的键,则返回默认值。

我可以通过使用defaultdict来做到这一点:

from collections import defaultdict

foo = defaultdict(lambda: "bar")
print(foo["hello"]) # "bar"

或通过使用常规dict并始终使用dict.get(key, default)来检索值:

foo = dict()
print(foo.get("hello", "bar")) # "bar"
print(foo["hello"]) # KeyError (as expected)

除了必须记住使用带有默认值而不是预期的括号语法的.get()明显的人体工程学开销之外,这两种方法之间有什么区别?

除了.get每个人的人体工程学之外,一个重要的区别是,如果您在defaultdict中查找缺少的键,它将向自身插入一个新元素,而不仅仅是返回默认值。 最重要的影响是:

  • 稍后的迭代将检索在defaultdict中查找的所有键
  • 随着更多最终存储在字典中,通常使用更多 memory
  • 默认值的突变会将该突变存储在defaultdict中,除非存储明确,否则.get默认值会丢失
from collections import defaultdict 
 
default_foo = defaultdict(list) 
dict_foo = dict()                                                                                                                                                                                                                                                                                           

for i in range(1024): 
    default_foo[i] 
    dict_foo.get(i, []) 
                                                                                                                                                                                                                                                                                                 
print(len(default_foo.items())) # 1024
print(len(dict_foo.items())) # 0

# Defaults in defaultdict's can be mutated where as with .get mutations are lost
default_foo[1025].append("123")
dict_foo.get(1025, []).append("123")

print(default_foo[1025]) # ["123"]
print(dict_foo.get(1025, [])) # []

这里的区别实际上归结为您希望程序如何处理 KeyError。

foo = dict()

def do_stuff_with_foo():
    print(foo["hello"])
    # Do something here
   
if __name__ == "__main__":
    try:
        foo["hello"] # The key exists and has a value
    except KeyError:
        # The first code snippet does this
        foo["hello"] = "bar"
        do_stuff_with_foo()

        # The second code snippet does this
        exit(-1)

问题是我们要完全停止该程序吗? 我们是希望用户为 foo["hello"] 填写一个值还是要使用默认值?

第一种方法是一种更紧凑的方式来执行foo.get("hello", "bar")但关键在于这是我们真正想要发生的事情吗?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM