Las funciones en Python son bloques de código reutilizables que estructuran los programas y los hacen mantenibles. Dominar funciones, parámetros, recursividad y closures es clave para superar entrevistas técnicas y escribir código de calidad profesional. Aquí tienes 20 ejercicios de Python con funciones resueltos, todos con código funcional y explicación.
Funciones básicas
Ejercicio 1 — Saludo personalizado con valor por defecto
def saludar(nombre, saludo="Hola"):
return f"{saludo}, {nombre}!"
print(saludar("Ana")) # Hola, Ana!
print(saludar("Luis", "Buenos dias")) # Buenos dias, Luis!
Ejercicio 2 — Calculadora básica
def calcular(a, b, operacion="suma"):
operaciones = {
"suma": a + b,
"resta": a - b,
"multiplicacion": a * b,
"division": a / b if b != 0 else "Error: division por cero"
}
return operaciones.get(operacion, "Operacion no valida")
print(calcular(10, 3, "resta")) # 7
Ejercicio 3 — Factorial iterativo
def factorial(n):
if n < 0:
return None
resultado = 1
for i in range(2, n + 1):
resultado *= i
return resultado
print(factorial(5)) # 120
Ejercicio 4 — Fibonacci con caché
from functools import lru_cache
@lru_cache(maxsize=None)
def fibonacci(n):
if n <= 1:
return n
return fibonacci(n - 1) + fibonacci(n - 2)
print([fibonacci(i) for i in range(10)])
# [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
Funciones con *args y **kwargs
Estos parámetros especiales permiten recibir un número variable de argumentos, algo muy habitual en librerías y frameworks Python.
Ejercicio 5 — Suma de argumentos variables
def sumar(*numeros):
return sum(numeros)
print(sumar(1, 2, 3)) # 6
print(sumar(10, 20, 30, 40)) # 100
Ejercicio 6 — Perfil de usuario con kwargs
def crear_perfil(nombre, **datos):
perfil = {"nombre": nombre}
perfil.update(datos)
return perfil
p = crear_perfil("Carlos", edad=28, ciudad="Madrid", rol="desarrollador")
print(p)
# {"nombre": "Carlos", "edad": 28, "ciudad": "Madrid", "rol": "desarrollador"}
Funciones lambda
Las funciones lambda son funciones anónimas de una sola expresión. Son muy útiles con sorted(), map() y filter().
Ejercicio 7 — Ordenar por longitud
palabras = ["Python", "es", "un", "lenguaje", "genial"]
ordenadas = sorted(palabras, key=lambda x: len(x))
print(ordenadas) # ["es", "un", "Python", "genial", "lenguaje"]
Ejercicio 8 — Map y filter con lambda
numeros = range(1, 21)
pares_al_cuadrado = list(map(lambda x: x**2, filter(lambda x: x % 2 == 0, numeros)))
print(pares_al_cuadrado)
# [4, 16, 36, 64, 100, 144, 196, 256, 324, 400]
Funciones recursivas
Ejercicio 9 — Búsqueda binaria recursiva
def busqueda_binaria(lista, objetivo, inicio=0, fin=None):
if fin is None:
fin = len(lista) - 1
if inicio > fin:
return -1
medio = (inicio + fin) // 2
if lista[medio] == objetivo:
return medio
elif lista[medio] < objetivo:
return busqueda_binaria(lista, objetivo, medio + 1, fin)
else:
return busqueda_binaria(lista, objetivo, inicio, medio - 1)
nums = [1, 3, 5, 7, 9, 11, 13]
print(busqueda_binaria(nums, 7)) # 3
Ejercicio 10 — Torres de Hanoi
def hanoi(n, origen, destino, auxiliar):
if n == 1:
print(f"Mover disco 1 de {origen} a {destino}")
return
hanoi(n - 1, origen, auxiliar, destino)
print(f"Mover disco {n} de {origen} a {destino}")
hanoi(n - 1, auxiliar, destino, origen)
hanoi(3, "A", "C", "B")
Closures y decoradores básicos
Ejercicio 11 — Contador con closure
def hacer_contador(inicio=0):
cuenta = [inicio]
def incrementar(paso=1):
cuenta[0] += paso
return cuenta[0]
return incrementar
contador = hacer_contador(10)
print(contador()) # 11
print(contador(5)) # 16
Ejercicio 12 — Decorador de tiempo de ejecución
import time
import functools
def medir_tiempo(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
inicio = time.time()
resultado = func(*args, **kwargs)
fin = time.time()
print(f"{func.__name__} tardo {fin - inicio:.4f}s")
return resultado
return wrapper
@medir_tiempo
def operacion_lenta():
time.sleep(0.1)
return "Listo"
operacion_lenta()
8 ejercicios adicionales para practicar
Amplia tu dominio de funciones avanzadas en Python con estos retos:
- Implementa una función que valide si un email tiene formato correcto usando solo lógica de strings.
- Crea un generador (
yield) que produzca números de Fibonacci indefinidamente. - Escribe una función que aplique otra función N veces a un valor inicial.
- Implementa
map()yfilter()desde cero sin usar los built-ins. - Crea un decorador que registre en log cada llamada a la función con sus argumentos.
- Escribe una función que convierta números romanos a enteros.
- Implementa
flatten()para listas anidadas de cualquier profundidad. - Crea una función
memoize()genérica sin usarlru_cache.
Preguntas frecuentes sobre funciones en Python
¿Cuál es la diferencia entre *args y **kwargs en Python?
*args permite pasar un número variable de argumentos posicionales, que la función recibe como una tupla. **kwargs permite pasar argumentos con nombre en cantidad variable, recibidos como un diccionario. Puedes combinar ambos: def funcion(*args, **kwargs). El nombre args y kwargs es solo una convención; lo importante son los asteriscos.
¿Qué es una función lambda y cuándo usarla?
Una función lambda es una función anónima de una sola expresión definida con la palabra clave lambda. Son ideales cuando necesitas una función simple de forma puntual, especialmente como argumento de sorted(), map() o filter(). Ejemplo: cuadrado = lambda x: x**2. Para funciones que necesiten más lógica o un nombre reutilizable, usa def.
¿Cuándo conviene usar recursividad en Python?
La recursividad es ideal cuando el problema tiene una estructura naturalmente recursiva: recorrido de árboles, algoritmos divide y vencerás (quicksort, mergesort) o cálculo de factorial y Fibonacci. En Python el límite por defecto de recursión es 1000 llamadas. Para problemas de gran profundidad, prefiere soluciones iterativas o activa la memorización con @lru_cache.
¿Qué es un closure en Python?
Un closure es una función interna que recuerda el estado del ámbito donde fue creada, incluso después de que ese ámbito haya terminado. Se forman cuando una función interna accede a variables de la función externa y esta devuelve la función interna. Son la base de los decoradores y permiten crear funciones con estado sin necesidad de clases.
Conclusión
Las funciones son el corazón de la programación en Python. Dominando parámetros, lambdas, recursividad y closures estarás listo para afrontar cualquier reto. Continúa practicando con los ejercicios de Python con listas y los ejercicios generales de Python.