python3 defaultdict使用方法与实现原理

转自: https://www.cnblogs.com/jidongdeatao/p/6930325.html

defaultdict类就好像是一个dict,但是它是使用一个类型来初始化的:

>>> from collections import defaultdict >>> dd = defaultdict(list) >>> dd defaultdict(<type 'list'>, {})

defaultdict类的初始化函数接受一个类型作为参数,当所访问的键不存在的时候,可以实例化一个值作为默认值:

>>> dd['foo'] [] >>> dd defaultdict(<type 'list'>, {'foo': []}) >>> dd['bar'].append('quux') >>> dd defaultdict(<type 'list'>, {'foo': [], 'bar': ['quux']})

需要注意的是,这种形式的默认值只有在通过dict.__getitem__(key)访问的时候才有效,这其中的原因在下文会介绍。

>>> from collections import defaultdict >>> dd = defaultdict(list) >>> 'something' in dd False >>> dd.pop('something') Traceback (most recent call last): File "", line 1, in <module> KeyError: 'pop(): dictionary is empty' >>> dd.get('something') >>> dd['something'] []

defaultdict类除了接受类型名称作为初始化函数的参数之外,还可以使用任何不带参数的可调用函数,到时该函数的返回结果作为默认值,这样使得默认值的取值更加灵活。下面用一个例子来说明,如何用自定义的不带参数的函数zero()作为defaultdict类的初始化函数的参数:

>>> from collections import defaultdict >>> def zero(): ... return 0 ... >>> dd = defaultdict(zero) >>> dd defaultdict(<function zero at 0xb7ed2684>, {}) >>> dd['foo'] 0 >>> dd defaultdict(<function zero at 0xb7ed2684>, {'foo': 0})

利用from collections import defaultdict strings = ('puppy', 'kitten', 'puppy', 'puppy','weasel', 'puppy', 'kitten', 'puppy') counts = defaultdict(lambda: 0) # 使用lambda来定义简单的函数 for s in strings: counts[s] += 1


defaultdict类是如何实现的

通过上面的内容,想必大家已经了解了defaultdict类的用法,那么在defaultdict类中又是如何来实现默认值的功能呢?这其中的关键是使用了看>>> from collections import defaultdict >>> printdefaultdict.__missing__.__doc__ __missing__(key) # Called by __getitem__ for missing key; pseudo-code: if self.default_factory is None: raise KeyError(key) self[key] =value = self.default_factory() return value

通过查看__getitem__()方法访问一个不存在的键时(dict[key]这种形式实际上是__missing__()方法获取默认值,并将该键添加到字典中去。

关于Mapping Types — dict"一节。

文档中介绍,从2.5版本开始,如果派生自dict的子类定义了__missing__()方法取得默认值。

从中可以看出,虽然dict支持>>> print dict.__missing__.__doc__ Traceback (most recent call last): File "", line 1, in <module> AttributeError: type object 'dict' has no attribute '__missing__'

同时,我们可以进一步的做实验,定义一个子类Missing并实现>>> class Missing(dict): ... def__missing__(self, key): ... return 'missing' ... >>> d = Missing() >>> d {} >>>d['foo'] 'missing' >>> d {}

返回结果反映了__missing__()方法,使得该子类同defautldict类一样为不存在的键设置一个默认值:

>>> class Defaulting(dict): ... def __missing__(self, key): ... self[key] = 'default' ... return 'default' ... >>> d = Defaulting() >>> d {} >>> d['foo'] 'default' >>> d {'foo': 'default'}

你可能感兴趣的:(Python)