J'ai remarqué que les deux fonctionnent de la même manière:
if x not in list
et if not x in list
.
Y a-t-il une sorte de différence entre les deux dans certains cas? Y a-t-il une raison d'avoir les deux, ou est-ce simplement parce qu'il est plus naturel pour certaines personnes d'écrire l'une ou l'autre?
Lequel suis-je le plus susceptible de voir dans le code des autres?
Les deux formulaires font un bytecode identique, comme vous pouvez clairement le vérifier:
>>> import dis
>>> dis.dis(compile('if x not in d: pass', '', 'exec'))
1 0 LOAD_NAME 0 (x)
3 LOAD_NAME 1 (d)
6 COMPARE_OP 7 (not in)
9 JUMP_IF_FALSE 4 (to 16)
12 POP_TOP
13 JUMP_FORWARD 1 (to 17)
>> 16 POP_TOP
>> 17 LOAD_CONST 0 (None)
20 RETURN_VALUE
>>> dis.dis(compile('if not x in d: pass', '', 'exec'))
1 0 LOAD_NAME 0 (x)
3 LOAD_NAME 1 (d)
6 COMPARE_OP 7 (not in)
9 JUMP_IF_FALSE 4 (to 16)
12 POP_TOP
13 JUMP_FORWARD 1 (to 17)
>> 16 POP_TOP
>> 17 LOAD_CONST 0 (None)
20 RETURN_VALUE
donc évidemment ils sont sémantiquement identiques.
Pour une question de style, PEP 8 ne mentionne pas le problème.
Personnellement, je préfère fortement le formulaire if x not in y
- qui indique immédiatement que not in
Est un opérateur unique, et "se lit comme l'anglais". if not x in y
Peut induire certains lecteurs en erreur en leur faisant croire que cela signifie if (not x) in y
, se lit un peu moins comme l'anglais et n'a absolument aucun avantage compensatoire.
>>> dis.dis(lambda: a not in b)
1 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (b)
6 COMPARE_OP 7 (not in)
9 RETURN_VALUE
>>> dis.dis(lambda: not a in b)
1 0 LOAD_GLOBAL 0 (a)
3 LOAD_GLOBAL 1 (b)
6 COMPARE_OP 7 (not in)
9 RETURN_VALUE
quand vous ne "pas a en b" il devra être converti pour (pas en)
donc, la bonne façon est "un pas en b".
not x in L
n'est pas explicitement interdit car ce serait idiot. x not in L
est explicitement autorisé (bien qu'il compile dans le même bytecode) car il est plus lisible.
x not in L
c'est ce que tout le monde utilise.
Lorsque vous écrivez a not in b
il utilise le not in
, tandis que not a in b
utilise l'opérateur in
puis annule le résultat. Mais le not in
L'opérateur est défini pour renvoyer la même chose que not a in b
donc ils font exactement la même chose. De la documentation :
Les opérateurs
in
etnot in
test pour l'appartenance à la collection.x in s
a la valeur true six
est membre de la collections
, et false sinon.x not in s
renvoie la négation dex in s
.
De même, il y a a is not b
contre not a is b
.
La syntaxe supplémentaire a été ajoutée car elle facilite la lecture naturelle par un humain.
C'est juste une préférence personnelle. Vous pouvez également comparer if x != 3
et if not x == 3
. Il n'y a aucune différence entre les deux expressions que vous avez montrées.