Je suis nouveau sur python et j'ai lu un extrait de code d'un endroit. C'est une implémentation du tri par comptage.
Le code est le suivant:
from collections import defaultdict
def sort_colors(A):
ht = {} # a hash map
ht = defaultdict(lambda:0, ht) # with default value 1
for i in A:
ht[i] += 1
ret = []
for k in [0, 1, 2]:
ret.extend([k]*ht[k])
return ret
Comme dans les deux premières lignes de la fonction, c'est
ht = {}
ht = defaultdict(lambda:0, ht)
Je ne suis pas tout à fait clair sur cette initialisation. Pourriez-vous m'aider à le comprendre? et aussi, devons-nous simplement remplacer ces deux lignes par les suivantes?
ht = defaultdict(int) # default value 0
Réponse courte (selon la réponse de Montaro ci-dessous)
defaultdict(lambda:1)
Réponse longue sur le fonctionnement de defaultdict
s
ht = {}
ht = defaultdict(lambda:0, ht)
defaultdict
s sont différents de dict
en ce que lorsque vous essayez d'accéder à un dict
normal avec une clé qui n'existe pas, il lève un KeyError
.defaultdict
, cependant, ne génère pas d'erreur: il crée la clé pour vous à la place. Avec quelle valeur? Avec le retour du callabe
vous avez passé en argument. Dans ce cas, chaque nouvelle clé sera créée avec la valeur 0
(Qui est le retour de la simple fonction lambda
lambda:0
), Qui se trouve également être le même retour de int()
, donc dans dans ce cas, il n'y aurait aucune différence à changer la fonction par défaut en int()
.
Décomposer cette ligne plus en détail: ht = defaultdict(lambda:0, ht)
Le premier argument est une fonction, qui est un objet appelable. Il s'agit de la fonction qui sera appelée pour créer une nouvelle valeur pour une clé inexistante. Le deuxième argument, ht
est facultatif et fait référence au dictionnaire de base sur lequel le nouveau defaultdict
sera construit. Par conséquent, si ht
avait des clés et des valeurs, le defaultdict
aurait également ces clés avec les valeurs correspondantes. Si vous essayez d'accéder à ces clés, vous obtiendrez les anciennes valeurs. Cependant, si vous ne transmettez pas le dictionnaire de base, un tout nouveau defaultdict
sera créé, et ainsi, toutes les nouvelles clés accédées recevront la valeur par défaut renvoyée par l'appelable.
(Dans ce cas, comme ht
est initialement un dict
vide, il n'y aurait aucune différence du tout en faisant ht = defaultdict(lambda:0)
, ht = defaultdict(int)
ou ht = defaultdict(lambda:0, ht)
: ils construiraient tous le même defaultdict
.
Je pense que vous pouvez simplement passer une fonction lambda qui retourne 1
d = defaultdict(lambda:1)