Maison > Article > développement back-end > Explication détaillée de defaultdict en Python (exemple de code)
Cet article vous apporte une explication détaillée (exemple de code) de defaultdict en Python. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Les valeurs par défaut peuvent être très pratiques
Comme nous le savons tous, en Python, si vous accédez à une clé qui n'existe pas dans le dictionnaire, une exception KeyError sera déclenché (en JavaScript, si une certaine clé n'existe pas dans l'attribut d'objet, renvoie undéfini). Mais il est parfois très pratique d’avoir une valeur par défaut pour chaque clé du dictionnaire. Par exemple, l'exemple suivant :
strings = ('puppy', 'kitten', 'puppy', 'puppy', 'weasel', 'puppy', 'kitten', 'puppy') counts = {} for kw in strings: counts[kw] += 1
Cet exemple compte le nombre de fois qu'un mot apparaît dans les chaînes et l'enregistre dans le dictionnaire des comptes. A chaque apparition d'un mot, la valeur stockée dans la clé correspondant aux comptes est incrémentée de 1. Mais en fait, l'exécution de ce code générera une exception KeyError. Le moment de l'occurrence correspond au moment où chaque mot est compté pour la première fois. Comme il n'y a pas de valeur par défaut dans le dict de Python, cela peut être vérifié dans la ligne de commande Python :
>>> counts = dict() >>> counts {} >>> counts['puppy'] += 1 Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'puppy'Utilisez des déclarations de jugement pour vérifier
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}Utilisez la méthode dict.setdefault() Vous pouvez également définir la valeur par défaut via la méthode dict.setdefault() :
strings = ('puppy', 'kitten', 'puppy', 'puppy', 'weasel', 'puppy', 'kitten', 'puppy') counts = {} for kw in strings: counts.setdefault(kw, 0) counts[kw] += 1
La méthode dict.setdefault() reçoit deux paramètres Le premier paramètre est le nom de la clé et le deuxième paramètre est la valeur par défaut. Si la clé donnée n'existe pas dans le dictionnaire, la valeur par défaut fournie dans le paramètre est renvoyée ; sinon, la valeur enregistrée dans le dictionnaire est renvoyée ; Le code de la boucle for peut être réécrit en utilisant la valeur de retour de la méthode dict.setdefault() pour le rendre plus concis :
strings = ('puppy', 'kitten', 'puppy', 'puppy', 'weasel', 'puppy', 'kitten', 'puppy') counts = {} for kw in strings: counts[kw] = counts.setdefault(kw, 0) + 1Utilisez la classe collections.defaultdict
>>> from collections import defaultdict >>> dd = defaultdict(list) >>> dd defaultdict(<type 'list'>, {})La fonction d'initialisation de la classe defaultdict accepte un type comme paramètre Lorsque la clé accessible n'existe pas. , Vous pouvez instancier une valeur comme valeur par défaut :
>>> dd['foo'] [] >>> dd defaultdict(<type 'list'>, {'foo': []}) >>> dd['bar'].append('quux') >>> dd defaultdict(<type 'list'>, {'foo': [], 'bar': ['quux']})Il convient de noter que cette forme de valeur par défaut n'est valable que lors d'un accès via
ou dict[key]
. sera présenté ci-dessous. 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'] []En plus d'accepter le nom du type comme paramètre de la fonction d'initialisation, cette classe peut également utiliser n'importe quelle fonction appelable sans paramètres. À ce moment-là, le résultat de retour de la fonction sera utilisé comme paramètre. valeur par défaut, de sorte que la valeur par défaut La valeur est plus flexible. Ce qui suit utilise un exemple pour illustrer comment utiliser la fonction personnalisée zero() sans paramètres comme paramètre de la fonction d'initialisation :
>>> 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})Utilisez
pour résoudre le problème de statistiques de mots initial, le code est comme suit : 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] += 1Comment la classe defaultdict est implémentée Grâce au contenu ci-dessus, vous devez avoir compris l'utilisation de la classe defaultdict, donc comment implémenter la fonction de valeur par défaut dans le classe defaultdict Drap de laine ? La clé pour cela est d'utiliser la méthode __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 valueEn regardant la docstring de la méthode __missing__(), vous pouvez voir que lorsque vous utilisez la méthode __getitem__() pour accéder à un non- clé existante (la forme dict[key] est en fait une forme simplifiée de la méthode __getitem__()), la méthode __missing__() sera appelée pour obtenir la valeur par défaut et ajouter la clé au dictionnaire. Pour une introduction détaillée à la méthode __missing__(), veuillez vous référer à la section « Mapping Types — dict » dans la documentation officielle de Python. Introduit dans le document, à partir de la version 2.5, si une sous-classe dérivée de dict définit la méthode __missing__(), lors de l'accès à une clé inexistante, dict[key] appellera la méthode __missing__() pour obtenir valeur par défaut. On peut voir à partir de cela que bien que dict prenne en charge la méthode __missing__(), cette méthode n'existe pas dans dict lui-même, mais cette méthode doit être implémentée dans la sous-classe dérivée. Cela peut être facilement vérifié :
>>> print dict.__missing__.__doc__ Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: type object 'dict' has no attribute '__missing__'En même temps, nous pouvons faire d'autres expériences, définir une sous-classe Missing et implémenter la méthode __missing__() :
>>> class Missing(dict): ... def __missing__(self, key): ... return 'missing' ... >>> d = Missing() >>> d {} >>> d['foo'] 'missing' >>> d {}Renvoyer le résultat réflexion La méthode __missing__() fait son travail. Sur cette base, nous modifions légèrement la méthode __missing__() pour que cette sous-classe définisse une valeur par défaut pour les clés inexistantes comme la classe defautldict :
>>> class Defaulting(dict): ... def __missing__(self, key): ... self[key] = 'default' ... return 'default' ... >>> d = Defaulting() >>> d {} >>> d['foo'] 'default' >>> d {'foo': 'default'}Implémenter defaultdict dans les anciennes versions de Python La fonction defaultdict a été ajoutée après la version 2.5 et n'est pas prise en charge dans certaines anciennes versions. Il est donc nécessaire d'implémenter une classe defaultdict compatible pour les anciennes versions. C'est en fait très simple. Bien que les performances ne soient pas aussi bonnes que celles de la classe par défaut fournie avec la version 2.5, elles sont fonctionnellement les mêmes.
class defaultdict(dict): def __getitem__(self, key): try: return dict.__getitem__(self, key) except KeyError: return self.__missing__(key)doit être implémentée pour définir la valeur par défaut value :
__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 valuedoit accepter les paramètres de type ou de fonction appelable :
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
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!