Come posso verificare se qualcosa è (non) in un elenco in Python?
La soluzione più economica e più leggibile sta utilizzando l' inoperatore (o nel tuo caso specifico not in). Come menzionato nella documentazione,
Gli operatori ine not intest per l'adesione. x in svaluta
Truese xè membro di s, e Falsealtrimenti. x not in srestituisce la negazione di x in s.
Inoltre,
L'operatore not inè definito per avere il valore reale inverso di in.
y not in xè logicamente uguale a not y in x.
Ecco alcuni esempi:
'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
Questo funziona anche con le tuple, poiché le tuple sono irritabili (come conseguenza del fatto che sono anche immutabili):
(1, 2) in [(3, 4), (1, 2)]
# True
Se l'oggetto su RHS definisce un __contains__()metodo, inlo chiamerà internamente, come indicato nell'ultimo paragrafo della sezione Confronti dei documenti.
... ine not insono supportati da tipi iterabili o implementano il
__contains__()metodo. Ad esempio, potresti (ma non dovresti) fare questo:
[3, 2, 1].__contains__(1)
# True
incortocircuiti, quindi se il tuo elemento è all'inizio dell'elenco, invaluta più velocemente:
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)
Se vuoi fare di più che controllare se un elemento è in un elenco, ci sono opzioni:
list.indexpuò essere utilizzato per recuperare l'indice di un elemento. Se quell'elemento non esiste, ValueErrorviene sollevato a.
list.count può essere utilizzato se si desidera contare le occorrenze.
Il problema XY: hai considerato sets?
Ponetevi queste domande:
- devi verificare se un elemento è in un elenco più di una volta?
- Questo controllo viene eseguito all'interno di un ciclo o una funzione chiamata ripetutamente?
- Gli elementi che stai memorizzando nel tuo elenco sono cancellabili? IOW, puoi chiamarli
hash?
Se hai risposto "sì" a queste domande, dovresti usare setinvece un . Un intest di appartenenza su lists è O (n) complessità temporale. Ciò significa che python deve eseguire una scansione lineare dell'elenco, visitando ogni elemento e confrontandolo con l'elemento di ricerca. Se lo fai ripetutamente o se gli elenchi sono grandi, questa operazione comporterà un sovraccarico.
setgli oggetti, d'altra parte, eseguono l'hashing dei loro valori per un controllo costante dell'appartenenza a tempo. Il controllo viene inoltre eseguito utilizzando in:
1 in {1, 2, 3}
# True
'a' not in {'a', 'b', 'c'}
# False
(1, 2) in {('a', 'c'), (1, 2)}
# True
Se sei abbastanza sfortunato che l'elemento che stai cercando / non stai cercando sia alla fine della tua lista, Python avrà scannerizzato la lista fino alla fine. Ciò è evidente dai tempi seguenti:
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)
Come promemoria, questa è un'opzione adatta a condizione che gli elementi che stai memorizzando e guardando siano hash. IOW, dovrebbero essere tipi immutabili o oggetti che implementano __hash__.
3 -1 > 0 and (4-1 , 5) not in []⤇Truepertanto l'errore non è una priorità dell'operatore.