¿Cómo verifico si algo está (no) en una lista en Python?
La solución más barata y más legible es usar el inoperador (o en su caso específico not in). Como se menciona en la documentación,
Los operadores iny not inprueba de membresía. x in sevalúa
Truesi xes miembro de s, y de lo Falsecontrario. x not in sdevuelve la negación de x in s.
Adicionalmente,
El operador not inse define para tener el valor verdadero inverso de in.
y not in xes lógicamente lo mismo que not y in x.
Aquí están algunos ejemplos:
'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
Esto también funciona con las tuplas, ya que las tuplas son hashable (como consecuencia del hecho de que también son inmutables):
(1, 2) in [(3, 4), (1, 2)]
# True
Si el objeto en el RHS define un __contains__()método, inlo llamará internamente, como se señala en el último párrafo de la sección de Comparaciones de los documentos.
... iny not inson compatibles con tipos que son iterables o implementan el
__contains__()método. Por ejemplo, podría (pero no debería) hacer esto:
[3, 2, 1].__contains__(1)
# True
incortocircuitos, por lo que si su elemento está al principio de la lista, inevalúa más rápido:
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 desea hacer más que simplemente verificar si un elemento está en una lista, hay opciones:
list.indexse puede usar para recuperar el índice de un artículo. Si ese elemento no existe, ValueErrorse genera a.
list.count puede usarse si desea contar las ocurrencias.
El problema XY: ¿Has considerado sets?
Hágase estas preguntas:
- ¿necesita verificar si un artículo está en una lista más de una vez?
- ¿Se realiza esta comprobación dentro de un bucle o se llama repetidamente a una función?
- ¿Los elementos que está almacenando en su lista son hashable? IOW, ¿puedes llamarlos
hash?
Si respondió "sí" a estas preguntas, debería utilizar un seten su lugar. Una inprueba de membresía en lists es O (n) complejidad de tiempo. Esto significa que Python tiene que hacer un escaneo lineal de su lista, visitando cada elemento y comparándolo con el elemento de búsqueda. Si está haciendo esto repetidamente, o si las listas son grandes, esta operación generará una sobrecarga.
setLos objetos, por otro lado, calculan sus valores para la verificación de membresía de tiempo constante. La verificación también se realiza utilizando in:
1 in {1, 2, 3}
# True
'a' not in {'a', 'b', 'c'}
# False
(1, 2) in {('a', 'c'), (1, 2)}
# True
Si tiene la mala suerte de que el elemento que está buscando / no está buscando está al final de su lista, python habrá escaneado la lista hasta el final. Esto es evidente por los tiempos a continuación:
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)
Como recordatorio, esta es una opción adecuada siempre y cuando los elementos que está almacenando y buscando sean intercambiables. IOW, tendrían que ser tipos inmutables u objetos que se implementen __hash__.
3 -1 > 0 and (4-1 , 5) not in []⤇Truepor lo tanto, el error no es uno de precedencia de los operadores.