Comment puis-je vérifier si quelque chose est (pas) dans une liste en Python?
La solution la moins chère et la plus lisible utilise l' in
opérateur (ou dans votre cas spécifique not in
). Comme mentionné dans la documentation,
Les opérateurs in
et not in
test d'adhésion. x in s
évalue
True
si x
est membre de s
, et False
sinon. x not in s
renvoie la négation de x in s
.
Aditionellement,
L'opérateur not in
est défini pour avoir la valeur vraie inverse de in
.
y not in x
est logiquement le même que not y in x
.
Voici quelques exemples:
'a' in [1, 2, 3]
# False
'c' in ['a', 'b', 'c']
# True
'a' not in [1, 2, 3]
# True
'c' not in ['a', 'b', 'c']
# False
Cela fonctionne également avec les tuples, car les tuples sont lavables (en conséquence du fait qu'ils sont également immuables):
(1, 2) in [(3, 4), (1, 2)]
# True
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
et not in
, sont pris en charge par des types qui sont itérables ou implémentent la
__contains__()
méthode. Par exemple, vous pourriez (mais ne devriez pas) faire ceci:
[3, 2, 1].__contains__(1)
# True
in
court-circuits, donc si votre élément est au début de la liste, il est in
évalué plus rapidement:
lst = list(range(10001))
%timeit 1 in lst
%timeit 10000 in lst # Expected to take longer time.
68.9 ns ± 0.613 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
178 µs ± 5.01 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
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, un ValueError
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:
- avez-vous besoin de vérifier si un élément est dans la liste plus d'une fois?
- Cette vérification est-elle effectuée à l'intérieur d'une boucle ou d'une fonction appelée à plusieurs reprises?
- Les articles que vous stockez sur votre liste sont-ils lavables? IOW, pouvez-vous faire appel
hash
à eux?
Si vous avez répondu «oui» à ces questions, vous devriez plutôt utiliser un set
. Un in
test d'appartenance sur list
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 utilisant in
:
1 in {1, 2, 3}
# True
'a' not in {'a', 'b', 'c'}
# False
(1, 2) in {('a', 'c'), (1, 2)}
# True
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:
l = list(range(100001))
s = set(l)
%timeit 100000 in l
%timeit 100000 in s
2.58 ms ± 58.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
101 ns ± 9.53 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
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__
.
3 -1 > 0 and (4-1 , 5) not in []
⤇True
donc l'erreur n'est pas celle de la priorité de l'opérateur.