Estoy tratando de entender cómo funcionan las funciones integradas any()
y all()
Python.
Estoy tratando de comparar las tuplas para que si algún valor es diferente, volverá True
y si son todos iguales, volverá False
. ¿Cómo están trabajando en este caso para devolver [False, False, False]?
d
es un defaultdict(list)
.
print d['Drd2']
# [[1, 5, 0], [1, 6, 0]]
print list(zip(*d['Drd2']))
# [(1, 1), (5, 6), (0, 0)]
print [any(x) and not all(x) for x in zip(*d['Drd2'])]
# [False, False, False]
Que yo sepa, esto debería dar salida
# [False, True, False]
ya que (1,1) son iguales, (5,6) son diferentes y (0,0) son iguales.
¿Por qué está evaluando a Falso para todas las tuplas?
Respuestas:
Puede pensar aproximadamente
any
yall
como una serie de lógicosor
yand
operadores, respectivamente.alguna
any
regresaráTrue
cuando al menos uno de los elementos sea Verdad. Lea sobre la prueba del valor de la verdad.todas
all
True
solo volverá cuando todos los elementos sean Verdad.Mesa de la verdad
Nota 1: El caso iterable vacío se explica en la documentación oficial, como esta
any
Como ninguno de los elementos es verdadero, vuelve
False
en este caso.all
Como ninguno de los elementos es falso, vuelve
True
en este caso.Nota 2:
Otra cosa importante que debe saber
any
yall
es que cortocircuitará la ejecución en el momento en que sepan el resultado. La ventaja es que no es necesario consumir todo el iterable. Por ejemplo,Aquí,
(not (i % 6) for i in range(1, 10))
hay una expresión generadora que regresaTrue
si el número actual dentro de 1 y 9 es un múltiplo de 6.any
iteramultiples_of_6
y cuando se encuentra6
, encuentra un valor de Verdad, por lo que regresa de inmediatoTrue
y el restomultiples_of_6
no se repite. Eso es lo que vemos cuando imprimimoslist(multiples_of_6)
, el resultado de7
,8
y9
.Esta excelente cosa se usa muy inteligentemente en esta respuesta .
Con esta comprensión básica, si miramos su código, usted lo hace
lo que garantiza que, al menos, uno de los valores sea Verdad, pero no todos. Por eso está volviendo
[False, False, False]
. Si realmente quisiera verificar si ambos números no son iguales,fuente
bool(data) and all(...)
debería funcionar.any
yall
tomar iterables y devolverTrue
si alguno y todos (respectivamente) de los elementos sonTrue
.Si los iterables están vacíos,
any
devuelveFalse
yall
devuelveTrue
.Me estaba manifestando
all
yany
para estudiantes en clase hoy. En su mayoría estaban confundidos acerca de los valores de retorno para iterables vacíos. Explicarlo de esta manera provocó que se encendieran muchas bombillas.Comportamiento de atajos
Ellos
any
yall
ambos buscan una condición que les permita dejar de evaluar. Los primeros ejemplos que les di requieren que evalúen el valor booleano para cada elemento en toda la lista.(Tenga en cuenta que la lista literal no se evalúa perezosamente en sí misma ; podría obtener eso con un iterador , pero esto es solo para fines ilustrativos).
Aquí hay una implementación de Python de todos y cada uno:
Por supuesto, las implementaciones reales están escritas en C y son mucho más eficaces, pero puede sustituir lo anterior y obtener los mismos resultados para el código en esta (o en cualquier otra) respuesta.
all
all
comprueba si hay elementosFalse
(para que pueda regresarFalse
), luego regresaTrue
si ninguno de ellos lo fueFalse
.any
La forma en que
any
funciona es que comprueba si hay elementosTrue
(para que pueda devolverTrue), then it returns
Falseif none of them were
True`.Creo que si tiene en cuenta el comportamiento abreviado, comprenderá intuitivamente cómo funcionan sin tener que hacer referencia a una Tabla de Verdad.
Evidencia de
all
yany
atajo:Primero, crea un noisy_iterator:
y ahora solo recorramos las listas ruidosamente, usando nuestros ejemplos:
Podemos ver
all
paradas en el primer cheque falso booleano.Y se
any
detiene en la primera verificación booleana verdadera:La fuente
Miremos la fuente para confirmar lo anterior.
Aquí está la fuente de
any
:Y aquí está la fuente de
all
:fuente
Python/bltinmodule.c
- Lo agregué a lo anterior.Sé que esto es antiguo, pero pensé que podría ser útil mostrar cómo se ven estas funciones en el código. Esto realmente ilustra la lógica, mejor que el texto o una tabla IMO. En realidad, se implementan en C en lugar de Python puro, pero son equivalentes.
En particular, puede ver que el resultado para iterables vacíos es solo el resultado natural, no un caso especial. También puede ver el comportamiento de cortocircuito; en realidad sería más trabajo para que no haya cortocircuito.
Cuando Guido van Rossum (el creador de Python) propuso por primera vez agregar
any()
yall()
, los explicó simplemente publicando exactamente los fragmentos de código anteriores.fuente
El código en cuestión sobre el que está preguntando proviene de mi respuesta dada aquí . Estaba destinado a resolver el problema de comparar múltiples matrices de bits, es decir, colecciones de
1
y0
.any
yall
son útiles cuando puede confiar en la "veracidad" de los valores, es decir, su valor en un contexto booleano. 1 esTrue
y 0 esFalse
, una conveniencia que esa respuesta aprovechó. 5 también lo esTrue
, así que cuando mezclas eso en tus posibles entradas ... bueno. No funcionaEn su lugar, podría hacer algo como esto:
Carece de la estética de la respuesta anterior ( realmente me gustó la apariencia de
any(x) and not all(x)
), pero hace el trabajo.fuente
True
cuando los valores son diferentes, la longitud del conjunto debe ser 2, no 1.fuente
fuente
El concepto es simple:
fuente
fuente