cualquier función () en Python con una devolución de llamada
-
19-09-2019 - |
Pregunta
La biblioteca estándar de Python define un any()
función que
Devuelve verdadero si algún elemento de lo iterable es verdadero. Si el Iterable está vacío, devuelve falso.
Verifica solo si los elementos evalúan a True
. Lo que quiero 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)
Solución
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
Otros consejos
ningún la 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 ningún La función se trae de LISP o puede decir desde el enfoque de programación de funciones. Hay otra función que es opuesta a la que es todos
>>> 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.
Debe usar una "expresión del 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 "para", por lo que para su ejemplo puede usar:
any (e for e in [1, 2, 'joe'] if isinstance(e, int) and e > 0)
Ligera 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
Si bien los otros dieron buenas respuestas pitónicas (solo usaría la respuesta aceptada en la mayoría de los casos), solo quería señalar lo fácil que es hacer que su propia utilidad funcione 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
Sin embargo, creo que al menos lo definiría con el parámetro de función, ya que eso coincidiría más con las funciones integradas existentes como map () y filtro ():::
def any_lambda(function, iterable):
return any(function(i) for i in iterable)
El filtro puede funcionar, además de devolverle los elementos coincidentes
>>> filter(lambda e: isinstance(e, int) and e > 0, [1,2,'joe'])
[1, 2]
Puedes usar una combinación de any
y map
Si realmente quieres mantener tu notación Lambda así:
any(map(lambda e: isinstance(e, int) and e > 0, [1, 2, 'joe']))
Pero es mejor usar una expresión de generador porque no construirá toda la lista dos veces.
Si usted De Verdad Desea en línea una lambda en cualquier () que pueda 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 concluir la lambda sin nombre y asegurarse de que se invoque en cada pase agregando el ()
La ventaja aquí es que aún puedes aprovechar el cortocircuito de la evaluación de cualquiera cuando llegue al primer int