¡Esta es una revisión vieja del documento!
Tabla de Contenidos
Funciones
Bloque perteneciente al curso Introducción a la programación con Python.
Una función es un elemento de un programa que agrupa sentencias de programación que luego pueden ser utilizadas desde cualquier otra parte del programa. Las funciones pueden, opcionalmente, recibir datos de entrada (llamados parámetros o argumentos) y retornar datos de salida o resutlados.
Definición de nuevas funciones
La definición de una función debe hacerse una única vez antes de ser utilizada.
Una vez definida, la función perdura hasta el final de la ejecución del código del programa.
def siguiente_numero(n): return n + 1
Declarar o definir una función no la ejecuta.
type(siguiente_numero) # function
Llamada a función
Llamar a una función es hacer uso de la misma (ejecutar su código), pasándole entre paréntesis los datos de entrada (si los necesita) y recogiendo el resultado. Dicho resultado puede almacenarse en una variable.
siguiente_nunmero(8) # 9 x = 2 y = siguiente_numero(x) x, y # (2, 3)
Definición alternativa de función
Explicitando tipos de datos en parámetros y valor devuelto:
def saludar(nombre: str) -> str: ''' Esta función genera un saludo personalizado a la persona cuyo nombre se da como parámetro ''' return "Hola " + nombre
nombre = input("¿Cómo te llamas?") resultado = saludar(nombre) print(resultado)
from math import sqrt def segundo_grado(a: float, b: float, c: float) -> tuple: ''' Busca las raíces reales de una ecuación de segundo grado con la forma a*x**2 + b*x + c = 0 ''' d = b**2 - 4 * a * c if d >= 0: x1 = (-b + sqrt(d)) / (2 * a) x2 = (-b - sqrt(d)) / (2 * a) return x1, x2 else: return None
help(segundo_grado) Help on function
Uso:
a = float(input("Coeficiente a: ")) b = float(input("Coeficiente b: ")) c = float(input("Coeficiente c: ")) resultado = segundo_grado(a, b, c) if resultado: r, s = resultado print(r, s) else: print("No tiene soluciones reales")
Versión con excepciones (en lugar de devolver 'None'):
from math import sqrt def segundo_grado(a: float, b: float, c: float) -> tuple: ''' Busca las raíces reales de una ecuación de segundo grado con la forma a*x**2 + b*x + c = 0 En caso de no tener soluciones reales, causa excepción ''' d = b**2 - 4 * a * c if d >= 0: x1 = (-b + sqrt(d)) / (2 * a) x2 = (-b - sqrt(d)) / (2 * a) return x1, x2 else: raise ValueError(f"La ecuacion {a}*x**2 + {b}*x + {c} = 0 no tiene soluciones reales")
Uso:
Coeficiente a: 1 Coeficiente b: 0 Coeficiente c: 1 AQUI ERROR
Podemos capturar el error de la siguiente manera con try y except:
a = float(input("Coeficiente a: ")) b = float(input("Coeficiente b: ")) c = float(input("Coeficiente c: ")) try: resultado = segundo_grado(a, b, c) r, s = resultado print(r, s) except ValueError as error: print(error)
Cuando lo usamos:
Coeficiente a: 1 Coeficiente b: 0 Coeficiente c: 1 La ecuación 1.0*x**2 + 0.0*x + 1.0 = 0 no tiene soluciones reales.
Funciones anónimas en línea (lambda)
En Python, una función Lambda se refiere a una pequeña función anónima. Las llamamos “funciones anónimas” porque técnicamente carecen de nombre.
cubo = lambda x: x*x*x cubo(5) # 125 type(cubo) # function
palabras = ["charlie", "delta", "foxtrot", "echo"] # Ordenación según el orden por defecto para las strings: orden lexicográfico sorted(palabras) # ['charlie', 'delta', 'echo', 'foxtrot'] Se le puede pasar una función a 'sorted' sorted(palabras, key=len) # ['echo', 'delta', 'charlie', 'foxtrot'] def logitud_inv(s: str) -> float: return 1.0 / -len(s) sorted(palabras, key=longitud_inv) # ['charlie', 'foxtrot', 'delta', 'echo'] # Utilizando una función anónima: sorted(palabras, key=lambda s: -len(s)) # ['charlie', 'foxtrot', 'delta', 'echo']
# Crear una lista con las palabras que contenga 'e': list(filter(lambda s: 'e' in s, palabras)) # ['charlie', 'delta', 'echo']
# Crear una lista de elementos "mapeados" con la función que convierte a mayúsculas list(map(lambda p: p.upper(), palabras)) # ["CHARLIE", "DELTA", "FOXTROT", "ECHO"]
Funciones que no retornan valor (procedimientos)
def contar_hasta(n : int): for i in range(n): print(i+1)
Resultado de ejecución:
contar_hasta(10) 1 2 3 4 5 6 7 8 9 10
Existe una instrucción en Python que no hace nada: pass. Puede ser útil si no queremos definir una función o algo por el momento:
def do_nothing(): pass
Funciones generadoras
Funciones que no devuelven un resultado, sino un objeto que puede utilizarse como iterable y que en cada iteración provoca que la función genere un nuevo valor.
def impares(tope: int = None): i = 1 while i < tope: yield i # parecido a 'return', pero no finaliza la función i += 2 impares(20) # generator object g = impares(20) next(g) # 1 next(g) # 3 next(g) # 5 next(g) # 7 for a in impares(20): print(a) # 1 # 3 # 5 # 7 # 9 # 11 # 13 # 15 # 17 # 19
from random import randint def combinacion_loteria(): combinacion_ganadora = set() while len(combinacion_ganadora) < 6: n = randint(1, 49) if n in combinacion_ganadora: continue yield n combinacion_ganadora.add(n) # La usamos con un 'for' for b in combinacion_loteria(): print(b) # 45 # 36 # 43 # 1 # 31 # 11
Secuencia de Fibonacci. Cada término de la sucesión se define como la suma de los dos anteriores:
0 1 # 1 + 0 1 # 1 + 0 2 # 1 + 1 3 # 2 + 1 5 # 3 + 2 8 # 5 + 3 13 # 8 + 5 21 # 13 + 8
def fibonacci(tope : int): a = 0 b = 1 while not tope or a < tope: yield a c = a + b b, a = c, b # a = b; b = c
for t in fibonacci(200): print(t)
Vamos a buscar la proporción áurea (ojo, que esto no estoy seguro de que esté bien):
phi = 1 phi0 = 0 g = fibonacci() next(g) a = next(g) b = next(g) while abs(phi - phi0) > 1e-9: b = a a = next(g) phi0 = phi phi = b / a print(f"phi = {phi:.12f}")
Funciones recursivas
Funciones que se llaman a sí mismas. La recursividad es útil como método de simplificación de un problema complejo dividiendo el problema en subproblemas del mismo tipo.
Un buen ejemplo es el factorial de un número entero:
def factorial(n : int) -> int: if n > 0: return n * factorial(n - 1) else: return 1
Uso:
factorial(5) # 120 factorial(0) # 1
