resueltos - guardar funciones en python
¿Cómo funcionan todas las funciones de Python? (6)
Estoy tratando de entender cómo funcionan las funciones incorporadas de Python any()
y all()
.
Estoy tratando de comparar las tuplas de modo que si cualquier valor es diferente, devolverá True
y si son todas iguales, devolverá False
. ¿Cómo están trabajando en este caso para regresar [Falso, Falso, Falso]?
d
es un valor 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 producir
# [False, True, False]
ya que (1,1) son lo mismo, (5,6) son diferentes, y (0,0) son lo mismo.
¿Por qué está evaluando False para todas las tuplas?
¿Cómo funcionan
all
funciones de Python?
any
toma all
iterables y devuelve True
si alguno y todos (respectivamente) de los elementos son True
.
>>> any([0, 0.0, False, (), ''0'']), all([1, 0.0001, True, (False,)])
(True, True) # ^^^-- truthy non-empty string
>>> any([0, 0.0, False, (), '''']), all([1, 0.0001, True, (False,), {}])
(False, False) # ^^-- falsey
Si los iterables están vacíos, any
devuelve False
, y all
devuelven True
.
>>> any([]), all([])
(False, True)
Estaba demostrando all
y any
para los estudiantes en clase hoy. En general, estaban confundidos acerca de los valores de retorno para los iterables vacíos. Explicarlo de esta manera provocó que se enciendan muchas bombillas.
Comportamiento de atajo
Ellos, any
, ambos buscan una condición que les permita dejar de evaluar. Los primeros ejemplos que les pedí para evaluar el booleano para cada elemento en la lista completa.
(Tenga en cuenta que el literal de la lista no se evalúa perezosamente, puede obtenerlo con un iterador , pero esto es sólo para fines ilustrativos).
all
all
controles para que los elementos sean False
(para que pueda devolver False
), luego devuelve True
si ninguno de ellos era False
.
>>> all([1, 2, 3, 4]) # has to test to the end!
True
>>> all([0, 1, 2, 3, 4]) # 0 is False in a boolean context!
False # ^--stops here!
>>> all([])
True # gets to end, so True!
any
La forma en que funciona es que comprueba que los elementos sean True
(para que pueda devolver True), then it returns
False if none of them were
True`.
>>> any([0, 0.0, '''', (), [], {}]) # has to test to the end!
False
>>> any([1, 0, 0.0, '''', (), [], {}]) # 1 is True in a boolean context!
True # ^--stops here!
>>> any([])
False # gets to end, so False!
Creo que si se tiene en cuenta el comportamiento de cortocircuito, comprenderá intuitivamente cómo funcionan sin tener que hacer referencia a una Tabla de verdad.
Evidencia de all
y any
atajo:
Primero, crea un noisy_iterator:
def noisy_iterator(iterable):
for i in iterable:
print(''yielding '' + repr(i))
yield i
y ahora solo iteremos sobre las listas ruidosamente, usando nuestros ejemplos:
>>> all(noisy_iterator([1, 2, 3, 4]))
yielding 1
yielding 2
yielding 3
yielding 4
True
>>> all(noisy_iterator([0, 1, 2, 3, 4]))
yielding 0
False
Podemos ver all
paradas en la primera verificación booleana falsa.
Y any
parada en la primera verificación booleana verdadera:
>>> any(noisy_iterator([0, 0.0, '''', (), [], {}]))
yielding 0
yielding 0.0
yielding ''''
yielding ()
yielding []
yielding {}
False
>>> any(noisy_iterator([1, 0, 0.0, '''', (), [], {}]))
yielding 1
True
El código en cuestión que estás preguntando proviene de mi respuesta dada here . Tenía la intención de resolver el problema de comparar matrices de múltiples bits, es decir, colecciones de 1
y 0
.
any
y all
son útiles cuando puedes confiar en la "veracidad" de los valores, es decir, su valor en un contexto booleano. 1 es True
y 0 es False
, una conveniencia que esa respuesta aprovechó. 5 también es True
, así que cuando mezcles eso en tus posibles entradas ... bueno. No funciona
En su lugar, podría hacer algo como esto:
[len(set(x)) == 1 for x in zip(*d[''Drd2''])]
Carece de la estética de la respuesta anterior ( realmente me gustó el aspecto de any(x) and not all(x)
), pero hace el trabajo bien.
Puede pensar en general en any
y en all
series de operadores lógicos or
y, respectivamente.
alguna
any
devolverá True
cuando al menos uno de los elementos sea Truthy. Lea sobre Pruebas de Valor de la Verdad.
todas
all
devolverán True
solo cuando todos los elementos sean Truthy.
Mesa de la verdad
+-----------------------------------------+---------+---------+
| | any | all |
+-----------------------------------------+---------+---------+
| All Truthy values | True | True |
+-----------------------------------------+---------+---------+
| All Falsy values | False | False |
+-----------------------------------------+---------+---------+
| One Truthy value (all others are Falsy) | True | False |
+-----------------------------------------+---------+---------+
| One Falsy value (all others are Truthy) | True | False |
+-----------------------------------------+---------+---------+
| Empty Iterable | False | True |
+-----------------------------------------+---------+---------+
Nota 1: El caso iterable vacío se explica en la documentación oficial, como este
Devuelve
True
si cualquier elemento de iterable es verdadero. Si el iterable está vacío, devuelveFalse
Como ninguno de los elementos es verdadero, devuelve False
en este caso.
Devuelve
True
si todos los elementos de iterable son verdaderos ( o si el iterable está vacío ).
Como ninguno de los elementos es falso, devuelve True
en este caso.
Nota 2:
Otra cosa importante que debes saber sobre any
cosa es que cortocircuitará la ejecución, en el momento en que conozcan el resultado. La ventaja es que no es necesario consumir todo iterable. Por ejemplo,
>>> multiples_of_6 = (not (i % 6) for i in range(1, 10))
>>> any(multiples_of_6)
True
>>> list(multiples_of_6)
[False, False, False]
Aquí, (not (i % 6) for i in range(1, 10))
es una expresión de generador que devuelve True
si el número actual dentro de 1 y 9 es un múltiplo de 6. any
repite los multiples_of_6
y cuando cumple 6
, encuentra un valor Truthy, por lo que devuelve True
inmediato, y el resto de los multiples_of_6
no se itera. Eso es lo que vemos cuando imprimimos la list(multiples_of_6)
, el resultado de 7
, 8
y 9
.
Esta excelente cosa se usa muy inteligentemente en esta respuesta .
Con este conocimiento básico, si miramos tu código, lo haces
any(x) and not all(x)
lo que asegura que, al menos uno de los valores sea Truthy pero no todos. Es por eso que está regresando [False, False, False]
. Si realmente desea verificar si los dos números no son iguales,
print [x[0] != x[1] for x in zip(*d[''Drd2''])]
Sé que esto es viejo, 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 estos son equivalentes.
def any(iterable):
for item in iterable:
if item:
return True
return False
def all(iterable):
for item in iterable:
if not item:
return False
return True
En particular, puede ver que el resultado de los 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 que no haya cortocircuitos.
Cuando Guido van Rossum (el creador de Python) propuso por primera vez agregar any()
y all()
, los explicó simplemente publicando exactamente los fragmentos de código anteriores.
>>> any([False, False, False])
False
>>> any([False, True, False])
True
>>> all([False, True, True])
False
>>> all([True, True, True])
True
s = "eFdss"
s = list(s)
all(i.islower() for i in s ) # FALSE
any(i.islower() for i in s ) # TRUE