Question 'has_key ()' ou 'in'?


Je me demande ce qu'il vaut mieux faire:

d = {'a': 1, 'b': 2}
'a' in d
True

ou:

d = {'a': 1, 'b': 2}
d.has_key('a')
True

689
2017-08-24 16:30


origine


Réponses:


in est définitivement plus pythonique.

En réalité has_key() a été supprimé dans Python 3.x.


960
2017-08-24 16:33



in gagne la main, non seulement dans l'élégance (et ne pas être obsolète ;-) mais aussi dans la 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 vrai, vous remarquerez que d'habitude, en Python, la solution la plus rapide est plus élégante et pythonique; c'est pourquoi -mtimeit est si utile - ce n'est pas juste à propos de sauver une centaine de nanosecondes ici et là! -)


221
2017-08-24 18:12



Selon python docs:

has_key() est déconseillé en faveur de    key in d.


69
2017-08-24 16:33



Utilisation dict.has_key() si (et seulement si) votre code doit être exécutable par les versions de Python antérieures à 2.3 (quand key in dict a été présenté).


34
2017-08-24 22:11



Il y a un exemple où in tue réellement votre performance.

Si tu utilises in sur un conteneur O (1) qui implémente uniquement __getitem__ et has_key() mais non __contains__ vous allez transformer une recherche O (1) en une recherche O (N) (comme in revient à une recherche linéaire via __getitem__).

La correction est évidemment triviale:

def __contains__(self, x):
    return self.has_key(x)

19
2018-01-18 16:45



has_key est une méthode de dictionnaire, mais in travaillera sur toute collection, et même quand __contains__ est manquant, in utilisera toute autre méthode pour itérer la collection pour le découvrir.


12
2017-08-24 18:35



Python 2.x prend en charge has_key().

Prise en charge de Python 2.3+ et Python 3.x in.


10
2018-05-09 08:06



La solution de dict.has_key () est déconseillée, utilisez 'in' - éditeur de texte sublime 3

Ici j'ai pris un exemple de dictionnaire nommé 'ages' -

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"

10
2018-02-23 10:29



Expansion des 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

7
2017-12-30 05:16



Si votre intention est d'utiliser une valeur par défaut dans le cas où une clé ne figure pas dans le dictionnaire alors

my_dict.get('key') or default_value

est une façon de sauter le in vérifier. get résultats None si la clé n'est pas dans le dictionnaire. La vitesse est également O (1) comme avec l'utilisation in.

Vous pouvez aussi utiliser

my_dict.get('key', default_value)

mais je trouve cela moins lisible.


4
2017-08-01 21:32



Si vous avez quelque chose comme ça

t.has_key(ew)

changez le en dessous pour courir sur Python 3.X et au-dessus

key = ew
if key not in t

4
2018-01-24 00:21