이 기사는 Python의 defaultdict에 대한 자세한 설명(코드 예제)을 제공합니다. 이는 특정 참조 가치가 있으므로 도움이 될 수 있습니다.
기본값은 매우 편리할 수 있습니다
우리 모두 알고 있듯이 Python에서는 사전에 존재하지 않는 키에 액세스하면 KeyError 예외가 발생합니다(JavaScript에서는 속성이 존재하지 않는 경우). 객체에 존재하는 경우 정의되지 않음이 반환됩니다). 그러나 때로는 사전의 모든 키에 대해 기본값을 갖는 것이 매우 편리합니다. 예를 들어 다음 예는 다음과 같습니다.
strings = ('puppy', 'kitten', 'puppy', 'puppy', 'weasel', 'puppy', 'kitten', 'puppy') counts = {} for kw in strings: counts[kw] += 1
이 예는 문자열에 단어가 나타나는 횟수를 계산하고 이를 counts 사전에 기록합니다. 단어가 나타날 때마다 개수에 해당하는 키에 저장된 값이 1씩 증가합니다. 그러나 실제로 이 코드를 실행하면 KeyError 예외가 발생합니다. Python 명령줄에서 확인할 수 있는 Python 사전에는 기본값이 없기 때문에 각 단어가 처음으로 계산될 때 발생합니다.
판단문을 사용하여 확인>>> counts = dict() >>> counts {} >>> counts['puppy'] += 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'puppy'
strings = ('puppy', 'kitten', 'puppy', 'puppy', 'weasel', 'puppy', 'kitten', 'puppy') counts = {} for kw in strings: if kw not in counts: counts[kw] = 1 else: counts[kw] += 1 # counts: # {'puppy': 5, 'weasel': 1, 'kitten': 2}
dict.setdefault에서 수신 () 메소드 두 개의 매개변수, 첫 번째 매개변수는 키의 이름이고 두 번째 매개변수는 기본값입니다. 주어진 키가 사전에 없으면 매개변수에 제공된 기본값이 반환되고, 그렇지 않으면 사전에 저장된 값이 반환됩니다. dict.setdefault() 메소드의 반환 값을 사용하면 for 루프의 코드를 더 간결하게 다시 작성할 수 있습니다.
strings = ('puppy', 'kitten', 'puppy', 'puppy', 'weasel', 'puppy', 'kitten', 'puppy') counts = {} for kw in strings: counts.setdefault(kw, 0) counts[kw] += 1
strings = ('puppy', 'kitten', 'puppy', 'puppy', 'weasel', 'puppy', 'kitten', 'puppy') counts = {} for kw in strings: counts[kw] = counts.setdefault(kw, 0) + 1
>>> from collections import defaultdict >>> dd = defaultdict(list) >>> dd defaultdict(<type 'list'>, {})
dict[key]
또는 dict.__getitem__(key)
를 통해 액세스할 때만 유효하다는 점에 유의해야 합니다. 그 이유는 아래에서 소개하겠습니다. >>> dd['foo'] [] >>> dd defaultdict(<type 'list'>, {'foo': []}) >>> dd['bar'].append('quux') >>> dd defaultdict(<type 'list'>, {'foo': [], 'bar': ['quux']})
dict[key]
或者dict.__getitem__(key)
访问的时候才有效,这其中的原因在下文会介绍。>>> from collections import defaultdict >>> dd = defaultdict(list) >>> 'something' in dd False >>> dd.pop('something') Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'pop(): dictionary is empty' >>> dd.get('something') >>> dd['something'] []
该类除了接受类型名称作为初始化函数的参数之外,还可以使用任何不带参数的可调用函数,到时该函数的返回结果作为默认值,这样使得默认值的取值更加灵活。下面用一个例子来说明,如何用自定义的不带参数的函数zero()作为初始化函数的参数:
>>> 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})
利用collections.defaultdict
来解决最初的单词统计问题,代码如下:
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类中又是如何来实现默认值的功能呢?这其中的关键是使用了看__missing__()这个方法:
>>> from collections import defaultdict >>> print defaultdict.__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
通过查看__missing__()方法的docstring,可以看出当使用__getitem__()方法访问一个不存在的键时(dict[key]这种形式实际上是__getitem__()方法的简化形式),会调用__missing__()方法获取默认值,并将该键添加到字典中去。
关于__missing__()方法的具体介绍可以参考Python官方文档中的"Mapping Types — dict"一节。
文档中介绍,从2.5版本开始,如果派生自dict的子类定义了__missing__()方法,当访问不存在的键时,dict[key]会调用__missing__()方法取得默认值。
从中可以看出,虽然dict支持__missing__()方法,但是在dict本身是不存在这个方法的,而是需要在派生的子类中自行实现这个方法。可以简单的验证这一点:
>>> print dict.__missing__.__doc__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'dict' has no attribute '__missing__'
同时,我们可以进一步的做实验,定义一个子类Missing并实现__missing__()方法:
>>> class Missing(dict): ... def __missing__(self, key): ... return 'missing' ... >>> d = Missing() >>> d {} >>> d['foo'] 'missing' >>> d {}
返回结果反映了__missing__()方法确实发挥了作用。在此基础上,我们稍许修改__missing__()方法,使得该子类同defautldict类一样为不存在的键设置一个默认值:
>>> class Defaulting(dict): ... def __missing__(self, key): ... self[key] = 'default' ... return 'default' ... >>> d = Defaulting() >>> d {} >>> d['foo'] 'default' >>> d {'foo': 'default'}
首先,__getitem__()方法需要在访问键失败时,调用__missing__()方法:
class defaultdict(dict): def __getitem__(self, key): try: return dict.__getitem__(self, key) except KeyError: return self.__missing__(key)
其次,需要实现__missing__()
方法用来设置默认值:
class defaultdict(dict): def __getitem__(self, key): try: return dict.__getitem__(self, key) except KeyError: return self.__missing__(key) def __missing__(self, key): self[key] = value = self.default_factory() return value
然后,defaultdict类的初始化函数__init__()
유형 이름을 초기화 함수의 매개변수로 허용하는 것 외에도 이 클래스는 매개변수 없이 호출 가능한 모든 함수를 사용할 수도 있습니다. 함수의 반환 결과가 기본값으로 사용되므로 기본값이 더 유연해집니다. . 다음은 매개변수 없이 사용자 정의 함수 zero()를 초기화 함수의 매개변수로 사용하는 방법을 보여주는 예입니다.
class defaultdict(dict): def __init__(self, default_factory=None, *a, **kw): dict.__init__(self, *a, **kw) self.default_factory = default_factory def __getitem__(self, key): try: return dict.__getitem__(self, key) except KeyError: return self.__missing__(key) def __missing__(self, key): self[key] = value = self.default_factory() return value
collections.defaultdict
를 사용하세요. :🎜try: from collections import defaultdictexcept ImportError: class defaultdict(dict): def __init__(self, default_factory=None, *a, **kw): dict.__init__(self, *a, **kw) self.default_factory = default_factory def __getitem__(self, key): try: return dict.__getitem__(self, key) except KeyError: return self.__missing__(key) def __missing__(self, key): self[key] = value = self.default_factory() return value
__missing__()
메서드를 구현해야 합니다. 🎜 rrreee🎜그런 다음 defaultdict 클래스 __init__()
의 초기화 함수는 유형 또는 호출 가능한 함수 매개변수를 허용해야 합니다. 🎜class defaultdict(dict): def __init__(self, default_factory=None, *a, **kw): dict.__init__(self, *a, **kw) self.default_factory = default_factory def __getitem__(self, key): try: return dict.__getitem__(self, key) except KeyError: return self.__missing__(key) def __missing__(self, key): self[key] = value = self.default_factory() return value
最后,综合以上内容,通过以下方式完成兼容新旧Python版本的代码:
try: from collections import defaultdictexcept ImportError: class defaultdict(dict): def __init__(self, default_factory=None, *a, **kw): dict.__init__(self, *a, **kw) self.default_factory = default_factory def __getitem__(self, key): try: return dict.__getitem__(self, key) except KeyError: return self.__missing__(key) def __missing__(self, key): self[key] = value = self.default_factory() return value
위 내용은 Python의 defaultdict에 대한 자세한 설명(코드 예)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!