J'utilise 'has_key()' ou 'dans' Python dicts?
Je me demande ce qui est le mieux à faire:
d = {'a': 1, 'b': 2}
'a' in d
True
ou:
d = {'a': 1, 'b': 2}
d.has_key('a')
True
Vous devez vous connecter pour publier un commentaire.
Je me demande ce qui est le mieux à faire:
d = {'a': 1, 'b': 2}
'a' in d
True
ou:
d = {'a': 1, 'b': 2}
d.has_key('a')
True
Vous devez vous connecter pour publier un commentaire.
in
est certainement plus pythonic.En fait
has_key()
a été supprimé en Python 3.x.in
fonctionne avec 2,6 trop à droite?keys()
est une vue similaire à celle de dans un dictionnaire plutôt que d'une copie, doncx in d.keys()
est O(1). Encore,x in d
est plus Pythonic.x in d.keys()
beaucoup plus lent quex in d
? (voir la réponse de @BrunoBronosky avec timeit pistes) Vous avez raison, mais il ne semble pas être l'O(1), mais plus de facteur constant (je vais voir sur 0.0361 vs 0.133 usec entre les deux faisant la timeit test localement, indépendamment de l'dict taille en Python 3.7)x in d.keys()
doit construire et de détruire un objet temporaire, complète avec l'allocation de mémoire que cela comporte, oùx in d.keys()
est juste de faire une opération arithmétique (calcul du hachage) et en faisant une recherche. Notez qued.keys()
est seulement d'environ 10 fois plus longtemps que cela, ce qui n'est pas vraiment long. Je n'ai pas vérifié, mais je suis encore assez sûr que c'est seulement O(1).in
gagne haut la main, et pas seulement dans l'élégance (et de ne pas être obsolète;-) mais aussi dans la performance, par exemple:Tandis que la suite de l'observation n'est pas toujours vrai, vous remarquerez que généralement, en Python, le plus rapide de la solution est plus élégante et Pythonic; c'est pourquoi
-mtimeit
est DONC utile -- ce n'est pas juste sur l'enregistrement d'une centaine de nanosecondes ici et là!-)has_key
semble être en O(1) trop.Selon python docs:
Utilisation
dict.has_key()
si (et seulement si) votre code est nécessaire pour être praticable par les versions de Python antérieures à 2.3 (quandkey in dict
a été introduit).Il y a un exemple où
in
effectivement tue votre performance.Si vous utilisez
in
sur un O(1) conteneur qui n'implémente__getitem__
ethas_key()
mais pas__contains__
vous tournez un O(1) recherche en O(N) de recherche (commein
revient à une recherche linéaire via__getitem__
).Correctif est évidemment trivial:
has_key()
est spécifique à Python 2 dictionnaires.in
/__contains__
est la bonne API à utiliser; pour les conteneurs où une analyse complète est inévitable, il n'y a pas dehas_key()
méthode de toute façon, et si il y a un O(1) approche alors ça va être du cas d'utilisation spécifiques et donc au développeur de choisir le bon type de données pour le problème.has_key
est un dictionnaire de la méthode, maisin
fonctionne sur n'importe quelle collection, et même quand__contains__
est manquant,in
va utiliser toute autre méthode pour effectuer une itération de la collection à découvrir.in
tests surrange
objets. Je ne suis pas si sûr de son efficacité sur Python 2xrange
, cependant. 😉__contains__
peut trivialement calculer si une valeur est dans la portée ou non.1.0 in range(10**2, 0, -1)
et puis essayez1.0 in range(10**10, 0, -1)
x in xrange(…)
, ce qui est clairement pas python3 et distinctement une mauvaise idée.xrange
mais alors que beaucoup de gens savent à traduire qu'àrange()
en Python 3 pas tout le monde est conscient qu'il yrange()
des tests de confinement est beaucoup plus efficace.Solution dict.has_key() est obsolète, utilisez 'dans' -- sublime éditeur de texte 3
Ici, j'ai pris un exemple de dictionnaire nommé 'âge' -
Expansion sur Alex Martelli de tests de performance avec Adam Parkin commentaires...
Python 2.x prend en charge
has_key()
.Python 2.3+ et Python 3.x
in
.has_key
est obsolète. Il n'y a rien de nouveau dans cette réponse sur le dessus 4 réponses postées 3 ans avant.Si vous avez quelque chose comme cela
modifier ci-dessous pour en cours d'exécution sur Python 3.X et au-dessus
t.has_key(ew)
retourneTrue
si la valeurew
références est également un élément clé dans le dictionnaire.key not in t
retourneTrue
si la valeur est pas dans le dictionnaire. En outre, lakey = ew
alias est très, très redondant. L'orthographe correcte estif ew in t
. Qui est ce que l'on a accepté de répondre à partir de 8 ans avant déjà dit.