Eu tenho uma lista de tuplas em Python e tenho uma condicional na qual quero assumir o ramo SOMENTE se a tupla não estiver na lista (se estiver na lista, não quero usar o ramo if)
if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList:
# Do Something
Isso realmente não está funcionando para mim. O que eu fiz errado?
python
list
conditional
membership
Zack
fonte
fonte
3 -1 > 0 and (4-1 , 5) not in []
⤇True
, portanto, o erro não é um dos precedência do operador.myList.count((curr_x, curr_y))
, se(curr_x, curr_y)
não está namyList
, o resultado será0
Respostas:
O bug provavelmente está em outro lugar no seu código, porque deve funcionar bem:
Ou com tuplas:
fonte
if not ELEMENT in COLLECTION:
A not in B
é reduzido a fazer onot B.__contains__(A)
que é o mesmo que o quenot A in B
é reduzido a qual énot B.__contains__(A)
.__notcontains__
. Sinto muito, então o que eu disse é apenas besteira.not
tiver maior precedência doin
que a que não tem. Considere o resultado doast.dump(ast.parse("not A in B").body[0])
qual resulta em"Expr(value=UnaryOp(op=Not(), operand=Compare(left=Name(id='A', ctx=Load()), ops=[In()], comparators=[Name(id='B', ctx=Load())])))"
Senot
agrupado firmemente em A, seria de esperar que o resultado fosse"Expr(value=Compare(left=UnaryOp(op=Not(), operand=Name(id='A', ctx=Load())), ops=[In()], comparators=[Name(id='B', ctx=Load())]))"
qual é a análise"(not A) in B"
.A solução mais barata e legível é usar o
in
operador (ou no seu caso específiconot in
). Conforme mencionado na documentação,Além disso,
y not in x
é logicamente o mesmo quenot y in x
.Aqui estão alguns exemplos:
Isso também funciona com tuplas, uma vez que as tuplas são hashable (como conseqüência do fato de serem imutáveis):
Se o objeto no RHS definir um
__contains__()
método, elein
será chamado internamente, conforme observado no último parágrafo da seção Comparações dos documentos.in
curto-circuito, portanto, se o seu elemento estiver no início da lista,in
avalie mais rapidamente:Se você deseja fazer mais do que apenas verificar se um item está em uma lista, existem opções:
list.index
pode ser usado para recuperar o índice de um item. Se esse elemento não existir, aValueError
é gerado.list.count
pode ser usado se você quiser contar as ocorrências.O problema XY: você já considerou
set
s?Faça a si mesmo estas perguntas:
hash
-los?Se você respondeu "sim" a essas perguntas, deve usar um
set
. Umin
teste de associação emlist
s é 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.set
objetos, por outro lado, hash seus valores para verificação de associação em tempo constante. A verificação também é feita usandoin
: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:
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__
.fonte