J'ai une liste de tuples en Python , et j'ai une condition où je veux prendre la branche UNIQUEMENT si le tuple n'est pas dans la liste (s'il est dans la liste, alors je ne veux pas prendre la branche if)
if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList:
# Do Something
Mais cela ne fonctionne pas vraiment pour moi. Qu'est ce que j'ai mal fait?
3 -1 > 0 and (4-1 , 5) not in []
⤇True
donc l'erreur n'est pas celle de la priorité de l'opérateur.myList.count((curr_x, curr_y))
, si ce(curr_x, curr_y)
n'est pas le casmyList
, le résultat sera0
Réponses:
Le bogue est probablement ailleurs dans votre code, car il devrait fonctionner correctement:
Ou avec des tuples:
la source
if not ELEMENT in COLLECTION:
A not in B
se réduit à fairenot B.__contains__(A)
ce qui est le même que ce quinot A in B
est réduit à ce qui estnot B.__contains__(A)
.__notcontains__
. Je suis désolé, alors ce que j'ai dit n'est que des conneries.not
avoir une priorité plus élevée que cellein
qui ne l'est pas. Considérez le résultatast.dump(ast.parse("not A in B").body[0])
dont les résultats dans"Expr(value=UnaryOp(op=Not(), operand=Compare(left=Name(id='A', ctx=Load()), ops=[In()], comparators=[Name(id='B', ctx=Load())])))"
Sinot
groupé étroitement à A, on aurait pu s'attendre à ce que le résultat soit"Expr(value=Compare(left=UnaryOp(op=Not(), operand=Name(id='A', ctx=Load())), ops=[In()], comparators=[Name(id='B', ctx=Load())]))"
qui est l'analyse"(not A) in B"
.La solution la moins chère et la plus lisible utilise l'
in
opérateur (ou dans votre cas spécifiquenot in
). Comme mentionné dans la documentation,Aditionellement,
y not in x
est logiquement le même quenot y in x
.Voici quelques exemples:
Cela fonctionne également avec les tuples, car les tuples sont lavables (en conséquence du fait qu'ils sont également immuables):
Si l'objet sur le RHS définit une
__contains__()
méthode, l'in
appellera en interne, comme indiqué dans le dernier paragraphe de la section Comparaisons de la documentation.in
court-circuits, donc si votre élément est au début de la liste, il estin
évalué plus rapidement:Si vous voulez faire plus que simplement vérifier si un élément est dans une liste, il existe des options:
list.index
peut être utilisé pour récupérer l'index d'un élément. Si cet élément n'existe pas, unValueError
est levé.list.count
peut être utilisé si vous voulez compter les occurrences.Le problème XY: Avez-vous pensé à
set
s?Posez-vous ces questions:
hash
à eux?Si vous avez répondu «oui» à ces questions, vous devriez plutôt utiliser un
set
. Unin
test d'appartenance surlist
s est une complexité temporelle O (n). Cela signifie que python doit effectuer une analyse linéaire de votre liste, visiter chaque élément et le comparer à l'élément de recherche. Si vous effectuez cette opération à plusieurs reprises, ou si les listes sont volumineuses, cette opération entraînera une surcharge.set
les objets, d'autre part, hachent leurs valeurs pour la vérification d'appartenance à temps constant. La vérification se fait également en utilisantin
:Si vous avez la malchance que l'élément que vous recherchez / ne recherchez pas se trouve à la fin de votre liste, python aura parcouru la liste jusqu'à la fin. Cela ressort clairement des horaires ci-dessous:
Pour rappel, c'est une option appropriée tant que les éléments que vous stockez et recherchez sont lavables. IOW, ils devraient être soit des types immuables, soit des objets à implémenter
__hash__
.la source