Dans le code de quelqu'un d'autre, j'ai lu les deux lignes suivantes:
x = defaultdict(lambda: 0)
y = defaultdict(lambda: defaultdict(lambda: 0))
Comme l'argument de defaultdict est une fabrique par défaut, je pense que la première ligne signifie que lorsque j'appelle x [k] pour une clé k inexistante (telle qu'une instruction comme v = x [k]), la paire clé-valeur (k , 0) sera automatiquement ajouté au dictionnaire, comme si l'instruction x [k] = 0 était exécutée pour la première fois. Ai-je raison?
Et toi? Il semble que la fabrique par défaut crée un défaut par défaut avec 0 par défaut. Mais qu'est-ce que cela signifie concrètement? J'ai essayé de jouer avec lui dans Python Shell, mais je n'ai pas pu comprendre ce que c'est exactement.
Je pense que la première ligne signifie que lorsque j'appelle
x[k]
pour une clé inexistantek
(telle qu'une instruction commev=x[k]
), la paire clé-valeur(k,0)
sera automatiquement ajouté au dictionnaire, comme si l'instructionx[k]=0
est d'abord exécuté.
C'est vrai. Ceci est écrit de façon plus idiomatique
x = defaultdict(int)
Dans le cas de y
, lorsque vous faites y["ham"]["spam"]
, la clé "ham"
est inséré dans y
s'il n'existe pas. La valeur qui lui est associée devient un defaultdict
dans lequel "spam"
est automatiquement inséré avec une valeur de 0
.
C'est-à-dire, y
est une sorte de "à deux niveaux" defaultdict
. Si "ham" not in y
, puis en évaluant y["ham"]["spam"]
c'est comme faire
y["ham"] = {}
y["ham"]["spam"] = 0
en termes de dict
ordinaire.
Vous avez raison pour ce que fait le premier. Quant à y
, il créera un défaut par défaut avec 0 par défaut lorsqu'une clé n'existe pas dans y
, vous pouvez donc le considérer comme un dictionnaire imbriqué. Prenons l'exemple suivant:
y = defaultdict(lambda: defaultdict(lambda: 0))
print y['k1']['k2'] # 0
print dict(y['k1']) # {'k2': 0}
Pour créer une structure de dictionnaire imbriquée équivalente sans defaultdict, vous devez créer un dict interne pour y['k1']
puis définissez y['k1']['k2']
à 0, mais defaultdict fait tout cela en arrière-plan lorsqu'il rencontre des clés qu'il n'a pas vues:
y = {}
y['k1'] = {}
y['k1']['k2'] = 0
La fonction suivante peut aider à jouer avec cela sur un interprète pour améliorer votre compréhension:
def to_dict(d):
if isinstance(d, defaultdict):
return dict((k, to_dict(v)) for k, v in d.items())
return d
Cela renverra l'équivalent dict d'un dict imbriqué par défaut, qui est beaucoup plus facile à lire, par exemple:
>>> y = defaultdict(lambda: defaultdict(lambda: 0))
>>> y['a']['b'] = 5
>>> y
defaultdict(<function <lambda> at 0xb7ea93e4>, {'a': defaultdict(<function <lambda> at 0xb7ea9374>, {'b': 5})})
>>> to_dict(y)
{'a': {'b': 5}}
defaultdict
prend un argument zéro appelable à son constructeur, qui est appelé lorsque la clé n'est pas trouvée, comme vous l'avez expliqué correctement.
lambda: 0
Renverra bien sûr toujours zéro, mais la méthode préférée pour cela est defaultdict(int)
, qui fera la même chose.
Quant à la deuxième partie, l'auteur souhaite créer une nouvelle defaultdict(int)
, ou un dictionnaire imbriqué, chaque fois qu'une clé n'est pas trouvée dans le dictionnaire de niveau supérieur.
Toutes les réponses sont encore assez bonnes, je donne la réponse pour ajouter plus d'informations:
"defaultdict requiert un argument qui peut être appelé. Ce résultat de retour de cet objet appelable est la valeur par défaut que le dictionnaire renvoie lorsque vous essayez d'accéder au dictionnaire avec une clé qui n'existe pas."
Voici un exemple
SAMPLE= {'Age':28, 'Salary':2000}
SAMPLE = defaultdict(lambda:0,SAMPLE)
>>> SAMPLE
defaultdict(<function <lambda> at 0x0000000002BF7C88>, {'Salary': 2000, 'Age': 28})
>>> SAMPLE['Age']----> This will return 28
>>> SAMPLE['Phone']----> This will return 0 # you got 0 as output for a non existing key inside SAMPLE
y = defaultdict(lambda:defaultdict(lambda:0))
sera utile si vous essayez ceci y['a']['b'] += 1