dict和collections.defaultdict有什么区别?
4 个回答
让我们深入了解Python字典和Python defaultdict()
类
Python字典
字典是Python中一种数据结构,它可以以键值对的形式存储数据。
举个例子:
d = {'a': 2, 'b': 5, 'c': 6}
字典的问题
字典使用得很好,但如果遇到缺失的键就麻烦了。假设你在找一个键值对,但字典里没有这个值,这时你可能会遇到一个KeyError
的问题。就像这样:
d = {'a': 2, 'b': 5, 'c': 6}
d['z'] # z is not present in dict so it will throw a error
你会看到这样的错误信息:
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
d['z']
KeyError: 'z'
解决上述问题的方法
为了克服这个问题,我们可以使用不同的方法:
使用内置函数
setdefault
如果字典中有这个key
,就返回它的值。如果没有,就插入一个带有default
值的键,并返回default
。默认情况下,default
是None
:
>>> d = {'a' :2, 'b': 5, 'c': 6}
>>> d.setdefault('z', 0)
0 # returns 0
>>> print(d) # add z to the dictionary
{'a': 2, 'b': 5, 'c': 6, 'z': 0}
get
如果字典中有这个key
,就返回它的值;如果没有,就返回default
。如果没有提供默认值,默认值是None
,所以这个方法不会引发KeyError
:
>>> d = {'a': 2, 'b': 5, 'c': 6}
>>> d.get('z', 0)
0 # returns 0
>>> print(d) # Doesn't add z to the dictionary unlike setdefault
{'a': 2, 'b': 5, 'c': 6}
以上两种方法都是解决我们问题的办法,它们不会引发KeyError
。除了这两种方法,Python还有一个collections
模块可以处理这个问题。接下来我们深入了解一下defaultdict
:
defaultdict
defaultdict
可以在Python的collections模块中找到。你可以这样使用它:
from collections import defaultdict
d = defaultdict(int)
defaultdict
构造函数接受一个default_factory
作为参数,这个参数是一个可调用的对象。比如说:
int
:默认值是整数0
str
:默认值是空字符串""
list
:默认值是空列表[]
代码:
from collections import defaultdict
d = defaultdict(list)
d['a'] # access a missing key and returns an empty list
d['b'] = 1 # add a key-value pair to dict
print(d)
输出将是defaultdict(<class 'list'>, {'b': 1, 'a': []})
defaultdict
的工作方式与get()
和setdefault()
方法相同,那么什么时候使用它们呢?
什么时候使用get()
如果你特别需要返回某个键值对而不想遇到KeyError
,并且不希望在字典中更新内容,那么dict.get
是合适的选择。它会返回你指定的默认值,但不会修改字典。
什么时候使用setdefault()
如果你需要用默认的键值对来修改原始字典,那么setdefault
是合适的选择。
什么时候使用defaultdict
虽然setdefault
方法可以用defaultdict
实现,但与每次在setdefault
中提供默认值不同,我们可以在defaultdict
中一次性设置默认值。此外,setdefault
可以为不同的键提供不同的默认值。根据使用场景,两者各有优缺点。
在效率方面:
defaultdict
>setdefault()
或get()
defaultdict
的速度是get()
的两倍!
你可以在这里查看结果。
来源:- https://shirishweb.wordpress.com/2017/05/06/python-defaultdict-versus-dict-get/
使用普通字典(dict)
d={}
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d['Grapes'])# This gives Key Error
我们可以通过在普通字典中设置默认值来避免出现 KeyError 错误,下面我们来看看怎么做。
d={}
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d.get('Apple'))
print(d.get('Grapes',0)) # DEFAULTING
使用默认字典(defaultdict)
from collections import defaultdict
d = defaultdict(int) ## inside parenthesis we say what should be the default value.
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d['Grapes']) ##→ This gives Will not give error
使用用户自定义的函数来设置默认值。
from collections import defaultdict
def mydefault():
return 0
d = defaultdict(mydefault)
d['Apple']=50
d['Orange']=20
print(d['Apple'])
print(d['Grapes'])
总结
在普通字典中设置默认值是根据具体情况来定的,而在默认字典中,我们可以更普遍地提供默认值。
使用默认字典的效率是使用普通字典的两倍。想了解更多关于这个性能测试的信息,可以参考下面的链接: https://shirishweb.wordpress.com/2017/05/06/python-defaultdict-versus-dict-get/
区别在于,defaultdict
会在你还没有设置某个键的时候,自动给这个键一个默认值。如果你不使用 defaultdict
,那么你就得先检查这个键是否存在,如果不存在,就得手动给它设置一个值。
这里的 lambda 是在定义一个默认值的“工厂”。每当需要默认值的时候,这个函数就会被调用。你可以想象,默认值的生成函数可以更复杂一些。
Help on class defaultdict in module collections:
class defaultdict(__builtin__.dict)
| defaultdict(default_factory) --> dict with default factory
|
| The default factory is called without arguments to produce
| a new value when a key is not present, in __getitem__ only.
| A defaultdict compares equal to a dict with the same items.
|
(来自 help(type(collections.defaultdict()))
)
{}.setdefault
的功能类似,但它接受的是一个值,而不是一个工厂函数。它的作用是如果这个值还不存在,就给它设置一个值……这和 defaultdict
有点不同。