Réponses:
in est définitivement plus pythonique.
En fait has_key()a été supprimé dans 3.x Python .
keys()c'est juste une vue d'ensemble dans un dictionnaire plutôt qu'une copie, tout x in d.keys()comme O (1). Pourtant, x in dc'est plus Pythonic.
x in d.keys()doit construire et détruire un objet temporaire, avec l'allocation de mémoire qui en découle, où x in d.keys()fait juste une opération arithmétique (calcul du hachage) et fait une recherche. Notez que ce d.keys()n'est que 10 fois plus long que cela, ce qui n'est pas vraiment long. Je n'ai pas vérifié mais je suis toujours sûr que ce n'est que O (1).
in gagne haut la main, non seulement en élégance (et en n'étant pas déprécié ;-) mais aussi en performance, par exemple:
$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'
10000000 loops, best of 3: 0.0983 usec per loop
$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'
1000000 loops, best of 3: 0.21 usec per loop
Bien que l'observation suivante ne soit pas toujours vraie, vous remarquerez qu'en général , en Python, la solution la plus rapide est plus élégante et Pythonique; c'est pourquoi -mtimeitest si utile - il ne s'agit pas seulement d'économiser une centaine de nanosecondes ici et là! -)
has_keysemble être O (1) aussi.
Selon les documents python :
has_key()est déconseillé en faveur dekey in d.
has_key()est maintenant supprimé dans Python 3
Utilisez dict.has_key()si (et seulement si) votre code doit être exécutable par les versions Python antérieures à 2.3 (lors de key in dictson introduction).
Il y a un exemple où intue réellement votre performance.
Si vous utilisez insur un conteneur O (1) qui implémente uniquement __getitem__et has_key()non, __contains__vous transformerez une recherche O (1) en recherche O (N) (comme cela inrevient à une recherche linéaire via __getitem__).
Le correctif est évidemment trivial:
def __contains__(self, x):
return self.has_key(x)
has_key()est spécifique aux dictionnaires Python 2 . in/ __contains__est la bonne API à utiliser; pour les conteneurs où une analyse complète est inévitable, il n'y a de toute façon pas de has_key()méthode , et s'il existe une approche O (1), ce sera spécifique au cas d'utilisation et donc au développeur de choisir le bon type de données pour le problème.
has_keyest une méthode de dictionnaire, mais infonctionnera sur n'importe quelle collection, et même lorsqu'elle __contains__est manquante, inutilisera toute autre méthode pour itérer la collection pour le découvrir.
intests sur des rangeobjets. xrangeCependant, je ne suis pas sûr de son efficacité sur Python 2 . ;)
__contains__peut trivialement calculer si une valeur est dans la plage ou non.
rangeinstance à chaque fois. En utilisant une seule instance préexistante , le test "nombre entier dans la plage" est environ 40% plus rapide dans mes délais.
La solution à dict.has_key () est déconseillée, utilisez 'in' - sublime text editor 3
Ici, j'ai pris un exemple de dictionnaire nommé «âges» -
ages = {}
# Add a couple of names to the dictionary
ages['Sue'] = 23
ages['Peter'] = 19
ages['Andrew'] = 78
ages['Karren'] = 45
# use of 'in' in if condition instead of function_name.has_key(key-name).
if 'Sue' in ages:
print "Sue is in the dictionary. She is", ages['Sue'], "years old"
else:
print "Sue is not in the dictionary"
Développant les tests de performance d'Alex Martelli avec les commentaires d'Adam Parkin ...
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 301, in main
x = t.timeit(number)
File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 178, in timeit
timing = self.inner(it, self.timer)
File "<timeit-src>", line 6, in inner
d.has_key(12)
AttributeError: 'dict' object has no attribute 'has_key'
$ python2.7 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0872 usec per loop
$ python2.7 -mtimeit -s'd=dict.fromkeys(range(1999))' 'd.has_key(12)'
10000000 loops, best of 3: 0.0858 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d'
10000000 loops, best of 3: 0.031 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d'
10000000 loops, best of 3: 0.033 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d.keys()'
10000000 loops, best of 3: 0.115 usec per loop
$ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d.keys()'
10000000 loops, best of 3: 0.117 usec per loop
Si vous avez quelque chose comme ça:
t.has_key(ew)
changez-le ci-dessous pour fonctionner sur Python 3.X et supérieur:
key = ew
if key not in t
t.has_key(ew)renvoie Truesi la ewréférence des valeurs est également une clé dans le dictionnaire. key not in trenvoie Truesi la valeur n'est pas dans le dictionnaire. De plus, l' key = ewalias est très, très redondant. L'orthographe correcte est if ew in t. C'est ce que la réponse acceptée de 8 ans auparavant vous a déjà dit.