Como verifico se algo está (não) em uma lista no Python?
A solução mais barata e legível é usar o inoperador (ou no seu caso específico not in). Conforme mencionado na documentação,
Os operadores ine not inteste para associação. x in savalia
Truese xé um membro se de Falseoutra forma. x not in sretorna a negação de x in s.
Além disso,
O operador not inestá definido para ter o valor verdadeiro inverso de in.
y not in xé logicamente o mesmo que not y in x.
Aqui estão alguns exemplos:
'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
Isso também funciona com tuplas, uma vez que as tuplas são hashable (como conseqüência do fato de serem imutáveis):
(1, 2) in [(3, 4), (1, 2)]
# True
Se o objeto no RHS definir um __contains__()método, ele inserá chamado internamente, conforme observado no último parágrafo da seção Comparações dos documentos.
... ine not insão suportados por tipos que são iteráveis ou implementam o
__contains__()método. Por exemplo, você poderia (mas não deveria) fazer isso:
[3, 2, 1].__contains__(1)
# True
incurto-circuito, portanto, se o seu elemento estiver no início da lista, inavalie mais rapidamente:
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 você deseja fazer mais do que apenas verificar se um item está em uma lista, existem opções:
list.indexpode ser usado para recuperar o índice de um item. Se esse elemento não existir, a ValueErroré gerado.
list.count pode ser usado se você quiser contar as ocorrências.
O problema XY: você já considerou sets?
Faça a si mesmo estas perguntas:
- você precisa verificar se um item está em uma lista mais de uma vez?
- Essa verificação é feita dentro de um loop ou uma função é chamada repetidamente?
- Os itens que você está armazenando na sua lista são laváveis? IOW, você pode chamá
hash-los?
Se você respondeu "sim" a essas perguntas, deve usar um set. Um inteste de associação em lists é O (n) complexidade de tempo. Isso significa que o python precisa fazer uma varredura linear da sua lista, visitando cada elemento e comparando-o com o item de pesquisa. Se você estiver fazendo isso repetidamente, ou se as listas forem grandes, essa operação acarretará uma sobrecarga.
setobjetos, por outro lado, hash seus valores para verificação de associação em tempo constante. A verificação também é feita usando in:
1 in {1, 2, 3}
# True
'a' not in {'a', 'b', 'c'}
# False
(1, 2) in {('a', 'c'), (1, 2)}
# True
Se você é infeliz o suficiente para que o elemento que você está procurando / não esteja no final da sua lista, o python terá escaneado a lista até o final. Isso é evidente nos horários abaixo:
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)
Lembre-se de que essa é uma opção adequada, desde que os elementos que você está armazenando e procurando sejam laváveis. IOW, eles teriam que ser tipos imutáveis ou objetos implementados __hash__.
3 -1 > 0 and (4-1 , 5) not in []⤇True, portanto, o erro não é um dos precedência do operador.