HOWTO · Python

Convertir números enteros a números romanos en Python

Este tutorial le enseñará a convertir un número entero a números romanos en Python.

En esta página

Los números romanos usan siete símbolos: I representa 1, V representa 5, X representa 10, L representa 50, C representa 100, D representa 500 y M representa 1.000. Un símbolo menor delante de uno mayor indica una resta: IV representa 4 e IX, 9. El mismo patrón da XL (40), XC (90), CD (400) y CM (900). Un conversor voraz usa estas combinaciones para evitar repeticiones no válidas, como XXXX para representar 40.

Convertir números enteros a números romanos en Python

La siguiente función guarda los pares de símbolos ordenados de mayor a menor valor. En cada paso, añade un símbolo mientras el número restante sea igual o superior al valor de ese par y, después, resta dicho valor. Recorre toda la tabla de equivalencias, por lo que puede usar varias veces cada valor cuando sea necesario. El intervalo convencional de entrada para números romanos es de 1 a 3.999. La función no valida ese límite superior; para valores mayores que 3.999, repite M y puede devolver un número romano no estándar.

Ejecuta este ejemplo:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

roman_map = [
    (1000, "M"), (900, "CM"), (500, "D"), (400, "CD"),
    (100, "C"), (90, "XC"), (50, "L"), (40, "XL"),
    (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I"),
]

def into_roman(num=42):
    result = ""
    for value, symbol in roman_map:
        while num >= value:
            result += symbol
            num -= value
    return result

print(into_roman())
XLII

Este ejemplo convierte 42 en XLII: la tabla toma primero 40 como XL y luego usa I dos veces para representar el 2 restante. Pasa otro entero positivo a into_roman(num) para convertir cualquier otro valor dentro del intervalo convencional. El bucle while de la función añade un símbolo repetidamente cuando un valor aparece más de una vez; después, el bucle for externo considera los valores menores. Para 0 o un entero negativo, la función devuelve una cadena vacía porque solo procesa valores mientras num sea mayor que cero. Los números romanos no tienen un símbolo estándar para el cero, así que valida el intervalo en tu aplicación si esos valores deben rechazarse.

Usar la división para convertir números enteros a números romanos en Python

Un segundo enfoque usa la división entera y el resto. Recorre los mismos 13 valores en orden descendente. Para cada valor, num // value indica cuántas veces cabe su símbolo; el resto, num % value, pasa a ser el valor que se procesa en el siguiente paso. Esta versión produce el mismo número romano y muestra explícitamente el cociente y el resto. Al igual que la primera función, está pensada para el intervalo convencional de 1 a 3.999 y no impone el límite superior; para valores mayores que 3.999, repite M y puede devolver un número romano no estándar.

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

roman_map = {
    1000: "M", 900: "CM", 500: "D", 400: "CD",
    100: "C", 90: "XC", 50: "L", 40: "XL",
    10: "X", 9: "IX", 5: "V", 4: "IV", 1: "I",
}
order = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]

def into_roman_by_division(num=42):
    result = ""
    for value in order:
        quotient, num = divmod(num, value)
        result += roman_map[value] * quotient
    return result

print(into_roman_by_division())
XLII

Para 42, la entrada de 40 tiene cociente 1 y deja un resto de 2; la entrada de 1 aporta entonces dos símbolos I, lo que da XLII. El bucle sigue recorriendo todos los valores, incluso cuando el cociente es 0, y divmod actualiza el resto para el siguiente valor. Como la primera función, esta implementación está pensada para enteros positivos: con 0 devuelve una cadena vacía, y con un entero negativo la división de suelo de Python no representa una resta en números romanos. Si recibes datos externos, comprueba que el valor está dentro del intervalo admitido antes de llamar a cualquiera de las dos funciones.