Cómo corregir RecursionError en Python

Publicado el: 11/07/2026
Tempo de leitura: 5 minutos
Como resolver RecursionError em Python rapidamente

El error RecursionError en Python aparece cuando una función se llama a sí misma demasiadas veces sin alcanzar una condición de salida. El mensaje habitual es maximum recursion depth exceeded. En la mayoría de los casos, la solución correcta consiste en corregir el caso base, reducir la profundidad o sustituir la recursión por una estructura iterativa.

Aumentar el límite con sys.setrecursionlimit() puede ser apropiado en situaciones controladas, pero no debe utilizarse para ocultar una función que nunca termina.

Ejemplo de recursión infinita

def countdown(number):
    print(number)
    return countdown(number - 1)


countdown(5)

La función continúa después de llegar a cero porque no existe un caso base. Finalmente Python detiene la ejecución para proteger la pila.

La documentación oficial de RecursionError describe esta excepción como el resultado de superar la profundidad máxima del intérprete.

Añadir un caso base

def countdown(number):
    if number <= 0:
        print("Fin")
        return

    print(number)
    countdown(number - 1)


countdown(5)

El caso base debe detener todas las rutas posibles. No basta con escribir una condición que ciertos datos nunca alcanzan.

Comprobar que el problema se acerca al caso base

Una función recursiva correcta reduce o transforma el problema:

def factorial(number):
    if number < 0:
        raise ValueError(
            "El factorial requiere un entero no negativo"
        )

    if number in {0, 1}:
        return 1

    return number * factorial(number - 1)

Cada llamada utiliza number - 1, por lo que eventualmente llega a 1.

La guía de funciones en Python explica parámetros, retornos, validación y scope.

Error por una actualización incorrecta

def search(values, index=0):
    if index >= len(values):
        return None

    if values[index] == "target":
        return index

    return search(values, index)

El índice no cambia, por lo que la función repite el mismo estado. Corrige la llamada:

return search(values, index + 1)

Registrar o imprimir los argumentos de cada llamada ayuda a detectar estados repetidos.

Recursión mutua

El ciclo puede involucrar varias funciones:

def is_even(number):
    return is_odd(number - 1)


def is_odd(number):
    return is_even(number - 1)

Sin casos base, ambas funciones se llaman indefinidamente. Una corrección sería:

def is_even(number):
    if number == 0:
        return True
    return is_odd(abs(number) - 1)


def is_odd(number):
    if number == 0:
        return False
    return is_even(abs(number) - 1)

Para este problema concreto, number % 2 == 0 es mucho más simple. No utilices recursión cuando una expresión directa resuelve la tarea.

Consultar el límite actual

import sys

print(sys.getrecursionlimit())

El valor suele estar alrededor de mil llamadas, pero depende de la implementación y configuración.

La documentación oficial de getrecursionlimit() explica que el límite evita una recursión infinita que desborde la pila de C.

Aumentar el límite con precaución

import sys

sys.setrecursionlimit(2000)

Un valor demasiado alto puede provocar un cierre del intérprete o agotar la memoria. Solo aumenta el límite cuando:

  • el algoritmo tiene un caso base correcto;
  • la profundidad máxima es conocida;
  • los datos realmente requieren ese nivel;
  • se han probado alternativas iterativas;
  • el entorno soporta el cambio.

Convertir una función a un bucle

Un countdown no necesita recursión:

def countdown(number):
    while number > 0:
        print(number)
        number -= 1

    print("Fin")

El bucle utiliza memoria constante y admite valores grandes. La guía de bucles en Python explica iteración, range(), break y continue.

Recorrer un árbol con una pila explícita

Una función recursiva para recorrer nodos puede fallar en árboles muy profundos:

def traverse(node):
    print(node.value)

    for child in node.children:
        traverse(child)

Versión iterativa:

def traverse(root):
    stack = [root]

    while stack:
        node = stack.pop()
        print(node.value)
        stack.extend(reversed(node.children))

La lista funciona como una pila y evita depender de la pila de llamadas.

Recorrer un grafo sin ciclos infinitos

En grafos, además de la profundidad, debes controlar nodos visitados:

def visit(graph, start):
    visited = set()
    stack = [start]

    while stack:
        node = stack.pop()

        if node in visited:
            continue

        visited.add(node)
        stack.extend(graph.get(node, []))

    return visited

Sin visited, un ciclo como A → B → A provoca llamadas repetidas. La guía de sets en Python explica pruebas de pertenencia eficientes.

Memoización para cálculos repetidos

Una función puede terminar correctamente, pero repetir demasiado trabajo:

def fibonacci(number):
    if number < 2:
        return number

    return (
        fibonacci(number - 1)
        + fibonacci(number - 2)
    )

Utiliza caché:

from functools import lru_cache


@lru_cache(maxsize=None)
def fibonacci(number):
    if number < 2:
        return number

    return (
        fibonacci(number - 1)
        + fibonacci(number - 2)
    )

La memoización reduce llamadas repetidas, pero no elimina la profundidad lineal. Para números grandes, una versión iterativa sigue siendo más segura.

Versión iterativa de Fibonacci

def fibonacci(number):
    if number < 0:
        raise ValueError(
            "El número debe ser no negativo"
        )

    previous = 0
    current = 1

    for _ in range(number):
        previous, current = current, previous + current

    return previous

Esta versión utiliza memoria constante y no puede superar el límite de recursión.

Procesar JSON o estructuras anidadas

Datos externos pueden contener una profundidad inesperada. Una función recursiva debe validar la estructura:

def count_values(data, depth=0, max_depth=100):
    if depth > max_depth:
        raise ValueError(
            "La estructura supera la profundidad permitida"
        )

    if isinstance(data, dict):
        return sum(
            count_values(value, depth + 1, max_depth)
            for value in data.values()
        )

    if isinstance(data, list):
        return sum(
            count_values(value, depth + 1, max_depth)
            for value in data
        )

    return 1

Limitar la profundidad también protege servicios que procesan datos no confiables.

Capturar RecursionError

try:
    result = process_structure(data)
except RecursionError as error:
    raise ValueError(
        "La estructura es demasiado profunda"
    ) from error

Capturar la excepción puede mejorar el mensaje en una frontera de la aplicación, pero no reemplaza la corrección del algoritmo.

La guía de try y except en Python explica encadenamiento y manejo por capas.

Depurar la profundidad

def recursive_function(value, depth=0):
    print("  " * depth, value)

    if is_finished(value):
        return value

    next_value = transform(value)
    return recursive_function(
        next_value,
        depth + 1,
    )

Comprueba si next_value cambia realmente. También puedes utilizar breakpoints, logging o cProfile para observar llamadas repetidas.

La guía de cProfile en Python ayuda a detectar funciones llamadas demasiadas veces.

Recursión de cola

Python no aplica optimización general de tail calls. Incluso cuando la llamada recursiva es la última operación, cada llamada conserva un frame:

def factorial(number, accumulator=1):
    if number <= 1:
        return accumulator

    return factorial(
        number - 1,
        accumulator * number,
    )

Para profundidades grandes, convierte este patrón a un bucle.

Ejemplo completo de diagnóstico

def safe_countdown(number):
    if not isinstance(number, int):
        raise TypeError("Se requiere un entero")

    if number < 0:
        raise ValueError(
            "El número no puede ser negativo"
        )

    while number:
        print(number)
        number -= 1

    print("Fin")

La versión valida la entrada y evita por completo la profundidad recursiva.

Procedimiento recomendado

  1. Localiza la función repetida en el traceback.
  2. Comprueba el caso base.
  3. Verifica que cada llamada avance hacia él.
  4. Busca ciclos entre varias funciones o nodos.
  5. Prueba una versión iterativa.
  6. Añade memoización si existe trabajo repetido.
  7. Aumenta el límite solamente con una profundidad conocida.

Errores frecuentes

  • Aumentar el límite antes de revisar el caso base.
  • Modificar un argumento sin acercarlo a la salida.
  • Recorrer grafos sin registrar visitados.
  • Usar recursión para una repetición lineal simple.
  • Suponer que Python optimiza recursión de cola.
  • Confundir memoización con reducción de profundidad.
  • Capturar RecursionError y continuar con un resultado incompleto.

Conclusión

RecursionError casi siempre indica que el algoritmo no termina o que la profundidad supera lo razonable para la pila. Corrige primero el caso base y el progreso de los argumentos. Para listas largas, árboles profundos o grafos, utiliza una pila explícita o un bucle. Modifica el límite únicamente cuando el algoritmo sea correcto y la profundidad esté controlada.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Contenido del artículo

    Artículos relacionados

    Como resolver erro MemoryError em aplicações Python
    Resolución de Errores
    Foto de perfil de Leandro Hirt da Academify

    Cómo corregir MemoryError en Python

    Corrige MemoryError en Python con generadores, lotes, chunks de Pandas, tipos eficientes, tracemalloc y reducción de copias.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Detecção de vazamento de memória em aplicações Python
    Resolución de Errores
    Foto de perfil de Leandro Hirt da Academify

    Cómo detectar fugas de memoria en Python

    Aprende a detectar fugas de memoria en Python con tracemalloc, gc, snapshots, cachés, generadores y análisis de referencias.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Uso do cProfile para identificar gargalos em código Python
    Resolución de Errores
    Foto de perfil de Leandro Hirt da Academify

    cProfile en Python: encuentra cuellos de botella

    Aprende a usar cProfile en Python para medir funciones, ordenar resultados, analizar pstats y optimizar cuellos de botella con evidencia.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Como resolver problemas de caminhos de arquivos em scripts Python
    Resolución de Errores
    Foto de perfil de Leandro Hirt da Academify

    Cómo corregir FileNotFoundError en Python

    Corrige FileNotFoundError en Python revisando rutas relativas, directorio actual, pathlib, carpetas, Docker, nombres y manejo de excepciones.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026
    Como corrigir erro ModuleNotFoundError em Python rapidamente
    Resolución de Errores
    Foto de perfil de Leandro Hirt da Academify

    Cómo corregir ModuleNotFoundError en Python

    Corrige ModuleNotFoundError en Python comprobando pip, intérprete, venv, sys.path, estructura de paquetes, Docker y nombres conflictivos.

    Ler mais

    Tempo de leitura: 4 minutos
    11/07/2026
    Como corrigir ImportError em projetos Python rapidamente
    Resolución de Errores
    Foto de perfil de Leandro Hirt da Academify

    Cómo corregir ImportError en Python paso a paso

    Aprende a corregir ImportError en Python: nombres ausentes, archivos conflictivos, imports circulares, entornos, versiones y rutas de módulos.

    Ler mais

    Tempo de leitura: 5 minutos
    11/07/2026