web-dev-qa-db-fra.com

Ordre de syntaxe pour utiliser les mots clés «non» et «dans»

Lors des tests d'adhésion, nous pouvons utiliser:

x not in y

Ou bien:

not y in x

Il peut y avoir de nombreux contextes possibles pour cette expression selon x et y. Il peut s'agir d'une vérification de sous-chaîne, de l'appartenance à une liste, de l'existence d'une clé dict, par exemple.

  • Les deux formes sont-elles toujours équivalentes?
  • Y a-t-il une syntaxe préférée?
89
wim

Ils donnent toujours le même résultat.

En réalité, not 'ham' in 'spam and eggs' semble être un boîtier spécial pour effectuer une seule opération "pas dans", plutôt qu'une opération "dans", puis annuler le résultat:

>>> import dis

>>> def notin():
    'ham' not in 'spam and eggs'
>>> dis.dis(notin)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE    

>>> def not_in():
    not 'ham' in 'spam and eggs'
>>> dis.dis(not_in)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE    

>>> def not__in():
    not ('ham' in 'spam and eggs')
>>> dis.dis(not__in)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               7 (not in)
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

>>> def noteq():
    not 'ham' == 'spam and eggs'
>>> dis.dis(noteq)
  2           0 LOAD_CONST               1 ('ham')
              3 LOAD_CONST               2 ('spam and eggs')
              6 COMPARE_OP               2 (==)
              9 UNARY_NOT           
             10 POP_TOP             
             11 LOAD_CONST               0 (None)
             14 RETURN_VALUE      

J'avais pensé au début qu'ils donnaient toujours le même résultat, mais que not était à lui seul un opérateur de négation logique de faible priorité, qui pouvait être appliqué à a in b tout aussi facilement que toute autre expression booléenne, tandis que not in était un opérateur séparé pour plus de commodité et de clarté.

Le démontage ci-dessus était révélateur! Il semble que tandis que not est évidemment un opérateur de négation logique, la forme not a in b est un boîtier spécial pour qu'il n'utilise pas réellement l'opérateur général. Cela fait not a in b littéralement la même expression que a not in b, plutôt qu'une simple expression qui donne la même valeur.

103
Ben
  1. Non, il n'y a pas de différence.

    L'opérateur not in est défini pour avoir la valeur vraie inverse de in.

    documentation Python

  2. Je suppose que not in est préféré car il est plus évident et ils ont ajouté un cas spécial pour cela.
13
icktoofay

Leur signification est identique, mais le pep8 Python préfère le not in opérateur dans règle E71 :

E713: le test d'adhésion doit être not in

Voir aussi "Python if x is not None ou if not x is None? " pour un choix de style très similaire.

5
trincot

D'autres ont déjà indiqué très clairement que les deux déclarations sont, jusqu'à un niveau assez bas, équivalentes.

Cependant, je ne pense pas que qui que ce soit ait encore suffisamment souligné que, puisque cela vous laisse le choix, vous devriez

choisissez le formulaire qui rend votre code aussi lisible que possible.

Et pas nécessairement aussi lisible que possible pour n'importe qui , même si c'est bien sûr une bonne chose à viser. Non, assurez-vous que le code est aussi lisible que possible pour vous , car vous êtes celui qui est le plus susceptible de revenir plus tard sur ce code et essayez de le lire.

3
Tomas Aschan

En Python, il n'y a pas de différence. Et il n'y a aucune préférence.

2

Syntaxiquement, ils sont la même déclaration. Je serais prompt à déclarer que 'ham' not in 'spam and eggs' exprime une intention plus claire, mais j'ai vu du code et des scénarios dans lesquels not 'ham' in 'spam and eggs' donne une signification plus claire que l'autre.

1
Makoto