Tengo una lista de tuplas en Python , y tengo un condicional donde quiero tomar la rama SOLAMENTE si la tupla no está en la lista (si está en la lista, entonces no quiero tomar la rama if)
if curr_x -1 > 0 and (curr_x-1 , curr_y) not in myList:
# Do Something
Sin embargo, esto realmente no funciona para mí. ¿Qué he hecho mal?
3 -1 > 0 and (4-1 , 5) not in []
⤇True
por lo tanto, el error no es uno de precedencia de los operadores.myList.count((curr_x, curr_y))
, si(curr_x, curr_y)
no estámyList
, el resultado será0
Respuestas:
El error probablemente esté en otra parte de su código, porque debería funcionar bien:
O con tuplas:
fuente
if not ELEMENT in COLLECTION:
A not in B
se reduce a hacer lonot B.__contains__(A)
que es lo mismo que lo quenot A in B
se reduce a lo que esnot B.__contains__(A)
.__notcontains__
. Lo siento, entonces lo que dije es una mierda.not
tuviera mayor prioridad quein
la que no tiene. Considere el resultado de loast.dump(ast.parse("not A in B").body[0])
que resulta en"Expr(value=UnaryOp(op=Not(), operand=Compare(left=Name(id='A', ctx=Load()), ops=[In()], comparators=[Name(id='B', ctx=Load())])))"
Si senot
agrupa estrechamente a A, uno hubiera esperado que el resultado fuera"Expr(value=Compare(left=UnaryOp(op=Not(), operand=Name(id='A', ctx=Load())), ops=[In()], comparators=[Name(id='B', ctx=Load())]))"
cuál es el análisis"(not A) in B"
.La solución más barata y más legible es usar el
in
operador (o en su caso específiconot in
). Como se menciona en la documentación,Adicionalmente,
y not in x
es lógicamente lo mismo quenot y in x
.Aquí están algunos ejemplos:
Esto también funciona con las tuplas, ya que las tuplas son hashable (como consecuencia del hecho de que también son inmutables):
Si el objeto en el RHS define un
__contains__()
método,in
lo llamará internamente, como se señala en el último párrafo de la sección de Comparaciones de los documentos.in
cortocircuitos, por lo que si su elemento está al principio de la lista,in
evalúa más rápido:Si desea hacer más que simplemente verificar si un elemento está en una lista, hay opciones:
list.index
se puede usar para recuperar el índice de un artículo. Si ese elemento no existe,ValueError
se genera a.list.count
puede usarse si desea contar las ocurrencias.El problema XY: ¿Has considerado
set
s?Hágase estas preguntas:
hash
?Si respondió "sí" a estas preguntas, debería utilizar un
set
en su lugar. Unain
prueba de membresía enlist
s 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.set
Los objetos, por otro lado, calculan sus valores para la verificación de membresía de tiempo constante. La verificación también se realiza utilizandoin
: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:
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__
.fuente