Funciones en Python: def, return, parámetros y ejercicios

Actualizado el 29 de septiembre de 2026

Una función es un bloque de código con nombre que recibe datos, hace algo con ellos y devuelve un resultado. Sirven para no repetir código, pero sobre todo para dividir un problema grande en partes pequeñas que se pueden entender y probar por separado.

Ya las usaste: print(), len() y range() son funciones. En esta guía vas a ver cómo escribir las tuyas, la diferencia entre return y print, los parámetros opcionales y los errores que más aparecen.

Definir y llamar una función

def area_rectangulo(ancho, alto):
    return ancho * alto

resultado = area_rectangulo(3, 4)
print(resultado)  # 12

def define la función, seguido del nombre y los parámetros entre paréntesis. Al llamarla, los valores que pasas (3 y 4) son los argumentos, y se asignan a los parámetros en orden. return entrega el resultado a quien llamó la función y la termina en ese momento.

return no es lo mismo que print

def sumar_e_imprimir(a, b):
    print(a + b)

r = sumar_e_imprimir(2, 3)  # muestra 5 en pantalla
print(r)                    # None

print muestra un valor en pantalla, pero la función no lo entrega: quien la llama recibe None. Una función que calcula algo debería devolverlo con return, y dejar que quien la usa decida si imprimirlo, guardarlo o seguir calculando.

Parámetros con valor por defecto

def saludar(nombre, saludo="Hola"):
    return f"{saludo}, {nombre}"

saludar("Ana")                          # 'Hola, Ana'
saludar("Ana", "Buenos días")           # 'Buenos días, Ana'
saludar(saludo="Chao", nombre="Luis")   # 'Chao, Luis'

Un parámetro con valor por defecto es opcional. Los parámetros con valor por defecto van al final. Al llamar la función también se pueden pasar los argumentos por nombre, en cualquier orden, lo que hace más legibles las llamadas con varios parámetros.

Devolver varios valores

def dividir(a, b):
    return a // b, a % b

cociente, resto = dividir(17, 5)
print(cociente, resto)  # 3 2

Al separar valores con comas en el return, la función devuelve una tupla, que se puede desarmar en varias variables al recibirla.

Variables locales

Las variables que se crean dentro de una función, incluidos sus parámetros, solo existen dentro de ella y desaparecen cuando termina. Eso es bueno: una función no pisa las variables del resto del programa. Para que una función use un dato, lo más claro es pasárselo como parámetro, y para que entregue algo, devolverlo con return.

Errores comunes

Olvidar el return

def sumar(a, b):
    a + b        # se calcula, pero no se devuelve

print(sumar(1, 2))  # None

Una función sin return devuelve None. Si ves None donde esperabas un resultado, revisa que todos los caminos de la función terminen en un return, incluidos los de cada if.

Una lista como valor por defecto

def agregar(elemento, lista=[]):
    lista.append(elemento)
    return lista

agregar(1)   # [1]
agregar(2)   # [1, 2]  ¡la lista se mantuvo entre llamadas!

El valor por defecto se crea una sola vez, al definir la función, no en cada llamada. Con listas o diccionarios, eso significa que todas las llamadas comparten el mismo objeto. La forma correcta es usar None y crear la lista adentro:

def agregar(elemento, lista=None):
    if lista is None:
        lista = []
    lista.append(elemento)
    return lista

Llamar la función sin paréntesis

print(saludar) no ejecuta la función: muestra algo como <function saludar at 0x...>. Para llamarla hacen falta los paréntesis, aunque no reciba argumentos.

UnboundLocalError al modificar una variable de afuera

Si una función hace total = total + n y total se creó fuera de ella, Python la considera una variable local que todavía no tiene valor: UnboundLocalError: cannot access local variable 'total'. En vez de modificar variables externas, recibe el valor como parámetro y devuelve el nuevo.

Ejercicios resueltos

Intenta resolver cada ejercicio antes de abrir la solución: equivocarse y corregir es la parte que más enseña.

1.Área de un rectángulo o un cuadrado

Escribe una función area_rectangulo(ancho, alto=None) que devuelva el área. Si no se indica el alto, se trata de un cuadrado y el alto es igual al ancho.

  • area_rectangulo(3, 4) → 12
  • area_rectangulo(5) → 25
Punto de partida
def area_rectangulo(ancho, alto=None):
    ...
Ver solución
Solución
def area_rectangulo(ancho, alto=None):
    if alto is None:
        alto = ancho
    return ancho * alto

None como valor por defecto sirve para saber si el argumento llegó o no. Se compara con is None y no con if not alto:, porque esa segunda forma también trataría un alto de 0 como si no se hubiera pasado.

2.Mayor y menor de una lista

Escribe una función max_y_min(numeros) que devuelva el mayor y el menor de una lista no vacía, en ese orden, sin usar max() ni min().

  • max_y_min([4, 9, 1, 7]) → (9, 1)
  • max_y_min([5]) → (5, 5)
  • max_y_min([-2, -8, -1]) → (-1, -8)
Punto de partida
def max_y_min(numeros):
    ...
Ver solución
Solución
def max_y_min(numeros):
    mayor = numeros[0]
    menor = numeros[0]
    for n in numeros[1:]:
        if n > mayor:
            mayor = n
        if n < menor:
            menor = n
    return mayor, menor

La clave está en con qué valor partir. Si mayor partiera en 0, con una lista de puros negativos el resultado sería 0, que ni siquiera está en la lista. Partir con el primer elemento garantiza un valor real, y después se recorre el resto comparando.

Como se parte con el primer elemento, el bucle recorre numeros[1:], el resto de la lista. Con una lista de un solo elemento el bucle no da ninguna vuelta y se devuelve ese elemento como mayor y como menor, que es lo correcto.

3.Precio final con descuento e IVA

Escribe una función precio_final(precio, descuento=10, iva=19) que aplique primero el descuento (en porcentaje) y después el IVA, y devuelva el resultado redondeado a entero.

  • precio_final(10000) → 10710
  • precio_final(10000, 25) → 8925
  • precio_final(10000, descuento=0) → 11900
  • precio_final(5990, iva=0) → 5391
Punto de partida
def precio_final(precio, descuento=10, iva=19):
    ...
Ver solución
Solución
def precio_final(precio, descuento=10, iva=19):
    con_descuento = precio * (100 - descuento) / 100
    return round(con_descuento * (100 + iva) / 100)

Un descuento del 10 % deja el 90 % del precio, y un IVA del 19 % lo lleva al 119 %. Guardar el paso intermedio en con_descuento hace la cuenta más fácil de revisar. Con los valores por defecto, 10.000 queda en 9.000 y después en 10.710.

Los ejemplos muestran para qué sirven los argumentos con nombre: precio_final(5990, iva=0) cambia solo el IVA y deja el descuento por defecto, algo que con argumentos por posición obligaría a repetir el 10.

Practica Python con ejercicios a tu nivel

En Coditer resuelves ejercicios en el navegador, con tests automáticos que revisan tu código y una IA que te da pistas cuando te atascas. Practicar es gratis.