Las funciones son el método principal de organización y reutilización de código.
Las funciones tienen un nombre y se declaran con la palabra reservada
def
y devuelve un valor usando la palabra reservada
return
.
También tienen una lista de argumentos:
posicionales
por clave
argumentos agrupados
tupla de argumentos posicionales (*args)
diccionario de argumentos accedidos por clave (**kwargs)
Los argumentos por clave se usan para indicar valores por defecto y siempre se sitúan después de los argumentos posicionales.
In [1]:
# Función que suma 3 números y devuelve el resultado
# 2 argumentos posicionales (x, y) y 2 por clave (z1, z2)
def suma_varios(x, y, z1=2, z2=4):
m = x + y + z1 + z2
return m
In [2]:
resultado1 = suma_varios(2, 3)
resultado2 = suma_varios(2, 3, z2=1)
resultado1, resultado2
Out[2]:
Usamos *args para representar una tupla arbitraria de argumentos agrupados. No es necesario que el nombre sea
args
:
In [3]:
def suma_varios(x, y, *otros):
print( "x:", x )
print( "y:", y )
print("otros:", otros)
suma = 0
for i in otros:
suma = suma + i
return x + y + suma
suma_varios(1, 2, 1, 3, 5, 7, 11)
Out[3]:
Se pueden definir los argumentos agrupados después de los argumentos posiciones y por clave. Usamos **kwargs para representar una lista arbitraria de argumentos agrupados representada como un diccionario. Como en el caso anterior, no es necesario que el nombre sea kwargs:
In [4]:
def suma_varios(x, y, *otros, **mas):
print( "x:", x )
print( "y:", y )
print("otros:", otros)
print("mas:", mas)
if mas.get('borrame'):
x = 0
print('x vale %d' % x)
In [5]:
suma_varios(1,2,3,4,5,6,7,8,9, cien = 100 , mil = 1000, borrame = True)
VARIABLES Y PASO POR REFERENCIA
En una asignación de un valor a una variable, se crea una referencia al objeto que se encuentra en el lado derecho de la asignación. Esto es muy importante entenderlo cuando se trabaja con grandes volúmenes de datos.
In [6]:
a = [1, 3, 5]
a
Out[6]:
In [7]:
b = a
b
Out[7]:
Ambas viariables 'a' y 'b' referencian al mismo objeto (la lista [1, 3, 5]). Si se modifica cualquiera de ellos, se modifican los dos.
In [8]:
a.append(7)
b
Out[8]:
En Python el paso de argumentos a una función se hace por
referencia
, mientras que en otros lenguajes se permite paso por valor y paso por referencia.
In [9]:
def cambia(lista, num):
lista.append(num)
a = [1, 2, 4]
cambia(a, 9)
a
Out[9]:
FUNCIONES COMO ARGUMENTOS DE OTRAS FUNCIONES
Supongamos que tenemos una lista de ciudades que necesitamos 'limpiar' o 'formatear'.
In [10]:
ciudades = [' Madrid', ' BARcelona', 'SeVILLA ' ]
Para dar un formato uniforme a esta lista antes de realizar otras tareas de análisis, es necesario transformarla eliminado espacios en blanco y transformando cada nombre a tipo
título
.
In [11]:
# Primera opción
def formatear(lista):
resultado = []
for ciudad in lista:
ciudad = ciudad.strip() # elimina espacios en blanco
ciudad = ciudad.title() # tipo título
resultado.append(ciudad)
return resultado
In [12]:
formatear(ciudades)
Out[12]:
Una alternativa más flexible consiste en crear una lista de operaciones a realizar y posteriormente aplicarla a la lista de ciudades:
In [13]:
# Segunda opción
operaciones = [str.strip, str.title]
def formatear(lista, operaciones):
resultado = []
for ciudad in lista:
for op in operaciones:
ciudad = op(ciudad)
resultado.append(ciudad)
return resultado
formatear(ciudades, operaciones)
Out[13]:
In [14]:
# Tercera opción
def formatear(lista, fun):
resultado = []
for ciudad in lista:
nueva = fun(ciudad)
resultado.append(nueva)
return resultado
formatear(ciudades, str.upper)
Out[14]:
El uso de funciones como argumentos de otras funciones es una característica de los lenguajes funcionales. La función
map
de los lenguajes funcionales también está accesible en Python. Esta función aplica una función a una colección de objetos:
In [15]:
# Python 3.5 map devuelve un objeto iterable
m1 = map(str.strip , ciudades)
list(m1)
Out[15]:
In [16]:
m2 = map(str.title, map(str.strip , ciudades))
list(m2)
Out[16]:
FUNCIONES ANÓNIMAS (LAMBDA FUNCTIONS)
Las funciones anónimas son aquellas que no tiene nombre y se refieren a una única instrucción. Se declaran con la palabra reservada
lambda
.
Son funciones cortas.
In [17]:
# función normal
def producto(a):
return a * 2
# la función anónima equivalente:
resultado = lambda a: a * 2
producto(6), resultado(6)
Out[17]:
Las funciones lambda se utilizan mucho en análisis de datos ya que es muy usual transformar datos mediante funciones que tienen a otras funciones en sus argumentos.
Se usan funciones lambda en lugar de escribir funciones normales para hacer el código más claro y más corto.
In [18]:
# mutiplicar por 2 todos los números de una lista
s = [1, 2, 3, 4]
def doble(lista, f):
""" Devuelvo una nueva lista definida por comprensión """
return [ f(x) for x in lista ]
In [19]:
doble(s, producto)
Out[19]:
Pero el mismo efecto lo conseguimos mediante una función anónima, evitando así la definición de la función producto:
In [20]:
doble(s, lambda x: x * 2)
Out[20]:
In [ ]: