Programacion Funcional
Listas por comprensión (comprehension)
las listas por comprensión se basan en el uso de variables calculadas a partir de una iteración. Algunos ejemplos de listas creadas a partir de un bucle for pueden ser:
lista_ascendente = [ i for i in range(<maximo>)]
lista_cuadrado = [ i * i for i in range(<maximo>)]
lista_ambas = [ (i, i * i ) for i in range(<maximo>)]
Funciones Lambda
Las funciones lambda son funciones anónimas, las cuales se se definen así:
Esta forma de definirlas es útil para definir manejadores (handlers), es decir funciones que se ejecutan ante eventos específicos del programa.Tip: manejadores (handlers)
# definicion
def nombre_funcion(x):
return expresion(x)
# asignacion
handler_evento = nombre_funcion
Con el uso de funciones lambda, esta rutina se reduce a:
Funciones flecha
Las funciones lambda son análogas a las funciones flecha de JavaScript y se usan de modo sumilar.
Otro uso práctico de las funciones simplificadas es crear funciones que sólo se usarán en una única linea de código, ahorrando la definición y asiganción de nombre habitual. Este modo de uso es muy habitual dentro de funciones map()
, reduce()
, etc, las cuales se explican más adelante.
Si se requiere reutilización, a las funciones lambda se les puede asignar una variable para referenciarlas, el cual servirá como nombre de función:
Y se llaman como una función normal:función lambda: multiplicación
Tip: funciones con argumentos preasignados
Con las funciones lambda se puede crear variantes alternativas de otras funciones, por ejemplo asignándole valores a algunos argumentos de entrada. Por ejemplo: crear varias funciones que calculan distintas potencias de un número de entrada a partir de una función genérica.
Info
Nótese que las funciones lambda son reconocidas por el intérprete de Python como si fueran funciones normales.
Funciones de Orden Superior
Son funciones capaces de ejecutar a otras funciones especificadas por el usuario. Estas funciones son indicadas por su nombre como argumento de la funcion de orden superior.
def funcion_superior (valor_1, valor_2, funcion_usuario):
# codigo
# ...
funcion_usuario(parametros)
# ...
# Funcion orden superior
def incrementar_4 (x, f):
# 'f' es una funcion de entrada
return f(x) + 4
# Funcion externa
def triplicar(x):
return x*3
# Uso
x = 7
y = incrementar_4(x, triplicar)
print(y) # Da (x)*3+4 = 25
Closures
Las 'closures' son funciones de orden superior que dan como retorno una función definida internamente.
def nombre_closure():
def funcion_interna(argumentos):
# rutina
return retorno
return funcion_interna
#definicion
def sumar_diez():
def add(valor):
return valor + 10
return add #funcion interna como retorno
#uso
closure_sumar = sumar_diez()
print(closure_sumar(7)) # da 10 + 7 = 17
Una utilidad posible de las closures en englobar varias funciones internas alternativas y poder elegir una u otra dependiendo de un argumento.
Otra utilidad posible es la creación de decoradores, los cuales agregan características a las funciones. Más sobre los decoradores de Python.
Map
La función map()
es una funcion de orden superior que facilita el procesamiento de datos iterables (particularmente: listas) por una función especificada, "mapeando" cada elemento de los datos de entrada con los argumentos de la funcion y evitando así el uso de bucles y la asignacion elemento a elemento.
Sintaxis:
El retorno de la funcion map() es un objeto de clase map
(una instancia). Con la función list()
se convierte dicho objeto en una lista de valores, recuperando así los resultados de la función interna.
objeto_resultado = map(funcion, lista_entrada)
resultado = list(objeto_resultado)
Ejemplo: elevar al cuadado todos los elementos de un vector
def potencia_2 (x):
return x**2
vector = [2, 5, 14, 3]
objeto = map(potencia_2, vector)
cuadrado = list(objeto)
La funcion map()
admite multiples listas de entrada
def multiplicar(x,y):
return x*y
vector = [2, 5, 14, 3]
objeto = map(multiplicar, vector, vector)
cuadrado = list(objeto)
map()
acepta funciones lambda como argumento. Ejemplo:
Filter
filter()
es una función que filtra de la lista de entrada los valores que cumplen con una condición lógica definida por una función especificada.
Sintaxis:
Nuevamente la salida es un objeto de la clasefilter
y para leer la lista de elementos filtrados hay que recurrir a la funcion list()
.
Ejemplo: filtrar valores numericos mayores a diez de un vector
def mayor_a_10(x):
return True if x > 10 else False
vector = [2, 5, -1, 48,-9,-25, 14, 3]
objeto= filter(mayor_a_10, vector)
filtrados = list(objeto)
filter()
también acepta funciones lambda como argumento.
Reduce
reduce()
opera con todos los elementos de una lista de entrada, aplicándoles una función especificada de manera acumulativa. Esto permite trabajar con un número no predeterminado de argumentos agrupados dentro de una lista de entrada. Para ser utilizada debe ser importada previamente desde el módulo functools:
def producto(x, y):
return x*y
vector = [2, 5, -1, -3]
productoria = reduce(producto, vector)
# 'productoria' es 2*5*(-1)*(-3) = 30
reduce()
es un valor no hace falta hacer conversiones de tipo adicionales.
Partial
La función partial()
permite asignar valores prefijados a una función como argumentos. Devuelve como retorno un objeto de clase 'partial' el cual incluye toda la información agregada y que puede utilizarse como si fuera una función lambda. De esta forma con partial()
se puede crear una o varias funciones simplificadas.
La función partial()
debe importarse desde el módulo functools:
El formato general de esta función es:
En caso de no indicarse los nombres de los argumentos éstos se asignarán en orden de definición.Los objetos partial se usan igual que cualquier función:
Ejemplo Nª1: cuadrado y cubo con partial()
Ejemplo Nº1: crear varias funciones que calculan distintas potencias de un número de entrada.
Estas funciones se usan fácilmente invocándolas por su nombre:Ejemplo Nª2: potencias con partial()
En este ejemplo se crea una lista de funciones que calculan distintas potencias de un número de entrada.
De este modo el índice de la función lambda elegida representa el exponente elegido: