tengo algunos predicados, por ejemplo:Pointfree combinación función en Python
is_divisible_by_13 = lambda i: i % 13 == 0
is_palindrome = lambda x: str(x) == str(x)[::-1]
y quiere combinar lógicamente como en:
filter(lambda x: is_divisible_by_13(x) and is_palindrome(x), range(1000,10000))
La pregunta ahora es: ¿Puede dicha combinación puede escribir en una pointfree estilo, tales como:
filter(is_divisible_by_13 and is_palindrome, range(1000,10000))
Esto tiene, por supuesto, no el efecto deseado, porque el valor de verdad de las funciones lambda es True
y and
y or
son operadores de cortocircuito. Lo más parecido que se me ocurrió fue definir una clase P
que es un contenedor de predicado simple que implementa __call__()
y tiene los métodos and_()
y or_()
para combinar predicados. La definición de P
es el siguiente:
import copy
class P(object):
def __init__(self, predicate):
self.pred = predicate
def __call__(self, obj):
return self.pred(obj)
def __copy_pred(self):
return copy.copy(self.pred)
def and_(self, predicate):
pred = self.__copy_pred()
self.pred = lambda x: pred(x) and predicate(x)
return self
def or_(self, predicate):
pred = self.__copy_pred()
self.pred = lambda x: pred(x) or predicate(x)
return self
Con P
ahora puedo crear un nuevo predicado que es una combinación de predicados como esto:
P(is_divisible_by_13).and_(is_palindrome)
que es equivalente a la función lambda anteriormente. Esto se acerca más a lo que me gustaría tener, pero tampoco es sin puntos (los puntos son ahora los predicados en lugar de sus argumentos). Ahora la segunda pregunta es: ¿hay una forma mejor o más corta (tal vez sin paréntesis y puntos) para combinar predicados en Python que usar clases como P
y sin usar las funciones (lambda)?
Parece que está haciendo un gran esfuerzo para que un lenguaje no funcional se comporte como un lenguaje funcional. ¿Estás atado a Python? –
@Eric: Sí, tipo de. Mi código de Python está incrustado en un proyecto de C++ y no puedo cambiar a otro idioma. –