cualquier función() en Python con una devolución de llamada
functional-programming callback (8)
Leve mejora a la respuesta de Antoine P
>>> any(type(e) is int for e in [1,2,''joe''])
True
Para all()
>>> all(type(e) is int for e in [1,2,''joe''])
False
La biblioteca estándar de Python define una función any()
que
Devuelve True si cualquier elemento de iterable es verdadero. Si el iterable está vacío, devuelve False.
Comprueba solo si los elementos se evalúan como True
. Lo que quiero es que pueda especificar una devolución de llamada para saber si un elemento se ajusta a la factura como:
any([1, 2, ''joe''], lambda e: isinstance(e, int) and e > 0)
Debería usar una "expresión de generador", es decir, una construcción de lenguaje que puede consumir iteradores y aplicar filtro y expresiones en una sola línea:
Por ejemplo (i ** 2 for i in xrange(10))
es un generador para el cuadrado de los primeros 10 números naturales (0 a 9)
También permiten una cláusula "if" para filtrar el itens en la cláusula "for", por lo que para su ejemplo, puede usar:
any (e for e in [1, 2, ''joe''] if isinstance(e, int) and e > 0)
Qué tal si:
>>> any(isinstance(e, int) and e > 0 for e in [1,2,''joe''])
True
También funciona con all()
por supuesto:
>>> all(isinstance(e, int) and e > 0 for e in [1,2,''joe''])
False
el filtro puede funcionar, además te devuelve los elementos correspondientes
>>> filter(lambda e: isinstance(e, int) and e > 0, [1,2,''joe''])
[1, 2]
cualquier función devuelve verdadero cuando cualquier condición es verdadera.
>>> any(isinstance(e, int) and e > 0 for e in [0 ,0, 1])
True # Returns True because 1 is greater than 0.
>>> any(isinstance(e, int) and e > 0 for e in [0 ,0, 0])
False # Returns False because not a single condition is True.
En realidad, el concepto de cualquier función proviene de Lisp o puede decirse del enfoque de programación de funciones. Hay otra función que es justo lo contrario a ella es todo
>>> all(isinstance(e, int) and e > 0 for e in [1, 33, 22])
True # Returns True when all the condition satisfies.
>>> all(isinstance(e, int) and e > 0 for e in [1, 0, 1])
False # Returns False when a single condition fails.
Estas dos funciones son realmente geniales cuando se usan correctamente.
Mientras que los otros dieron buenas respuestas Pythonic (solo usaría la respuesta aceptada en la mayoría de los casos), solo quería señalar lo fácil que es hacer su propia función de utilidad para hacerlo usted mismo si realmente lo prefiere:
def any_lambda(iterable, function):
return any(function(i) for i in iterable)
In [1]: any_lambda([1, 2, ''joe''], lambda e: isinstance(e, int) and e > 0
Out[1]: True
In [2]: any_lambda([-1, ''2'', ''joe''], lambda e: isinstance(e, int) and e > 0)
Out[2]: False
Creo que al menos lo definiría primero con el parámetro de función, ya que eso coincidiría más con las funciones integradas existentes como map () y filter ():
def any_lambda(function, iterable):
return any(function(i) for i in iterable)
Puede usar una combinación de any
y map
si realmente desea mantener su notación lambda así:
any(map(lambda e: isinstance(e, int) and e > 0, [1, 2, ''joe'']))
Pero es mejor usar una expresión generadora porque no construirá toda la lista dos veces.
Si realmente desea alinear una lambda en cualquier (), puede hacer esto:
>>> any((lambda: isinstance(e, int))() for e in [1,2,''joe''])
True
>>> any((lambda: isinstance(e, int))() for e in [''joe''])
False
Solo tiene que cerrar el lambda sin nombre y asegurarse de que se invoca en cada pasada agregando el ()
La ventaja aquí es que todavía puede tomar ventaja de cortocircuitar la evaluación de cualquiera cuando golpea la primera int