Python Programming

Conversión eficiente de cadena a número en Python

Spread the love

Python ofrece varias maneras de convertir cadenas que representan números en sus contrapartes numéricas (flotantes o enteros). El método óptimo depende de factores como el formato de cadena de entrada esperado, las necesidades de manejo de errores y las consideraciones de rendimiento. Este artículo explora estas técnicas y sus compensaciones.

Tabla de contenido

  1. Usando float() para la conversión de cadena a flotante
  2. Usando int() para la conversión de cadena a entero
  3. Conversión segura con ast.literal_eval()
  4. Manejo de la localización y las comas
  5. Comparación de rendimiento de los métodos de conversión

1. Usando float() para la conversión de cadena a flotante

El enfoque más simple es usar la función float() integrada. Intenta analizar la cadena en su equivalente de punto flotante. Si la cadena no es una representación flotante válida (por ejemplo, contiene caracteres no numéricos), se genera un ValueError.


string_number = "3.14159"
float_number = float(string_number)
print(float_number)  # Salida: 3.14159

string_number = "10"
float_number = float(string_number)
print(float_number)  # Salida: 10.0

try:
    invalid_number = float("abc")
except ValueError:
    print("Cadena inválida para la conversión a flotante")  # Salida: Cadena inválida para la conversión a flotante

2. Usando int() para la conversión de cadena a entero

De manera similar, int() convierte cadenas a enteros. También genera un ValueError si la cadena no representa un número entero; las partes fraccionarias causarán un error.


string_number = "10"
int_number = int(string_number)
print(int_number)  # Salida: 10

try:
    invalid_number = int("3.14")
except ValueError:
    print("Cadena inválida para la conversión a entero")  # Salida: Cadena inválida para la conversión a entero

try:
    invalid_number = int("abc")
except ValueError:
    print("Cadena inválida para la conversión a entero")  # Salida: Cadena inválida para la conversión a entero

3. Conversión segura con ast.literal_eval()

La función ast.literal_eval() del módulo ast ofrece una alternativa más segura, especialmente cuando se trata de entradas no confiables. Analiza la cadena utilizando el Árbol de Sintaxis Abstracta (AST) de Python, evitando la ejecución de código malicioso incrustado en la cadena. Esto es vital para la seguridad al manejar datos externos.


import ast

string_number = "3.14159"
float_number = ast.literal_eval(string_number)
print(float_number)  # Salida: 3.14159

string_number = "10"
int_number = ast.literal_eval(string_number)
print(int_number)  # Salida: 10

try:
    unsafe_input = ast.literal_eval("__import__('os').system('rm -rf /')")  # Esto generará un error
except (ValueError, SyntaxError):
    print("ast.literal_eval previno la ejecución de código malicioso")

4. Manejo de la localización y las comas

En algunas configuraciones regionales, los números usan comas como separadores de miles (por ejemplo, «1,000.50»). float() no manejará esto directamente. Preprocese la cadena reemplazando las comas por puntos (o viceversa, según su configuración regional) antes de la conversión. El módulo locale puede ayudar en el formato específico de la configuración regional.


import locale

locale.setlocale(locale.LC_NUMERIC, 'en_US.UTF-8')  # Ejemplo para la configuración regional de EE. UU.

string_number = "1,000.50"
processed_number = string_number.replace(",", "")
float_number = float(processed_number)
print(float_number)  # Salida: 1000.5

#Para configuraciones regionales que usan '.' como separador de miles y ',' como separador decimal
string_number = "1.000,50"
processed_number = string_number.replace(".", "").replace(",", ".")
float_number = float(processed_number)
print(float_number) #Salida: 1000.5

5. Comparación de rendimiento de los métodos de conversión

float() e int() son generalmente los más rápidos. ast.literal_eval() es más lento debido a la sobrecarga del análisis de AST. Sin embargo, sus beneficios de seguridad a menudo superan la diferencia de rendimiento, especialmente con entradas no confiables. Para conjuntos de datos grandes donde el rendimiento es crucial y los datos son confiables, se prefieren float() e int(). Para conjuntos de datos más pequeños o cuando la seguridad es primordial, ast.literal_eval() es una opción más segura. La evaluación comparativa con timeit puede proporcionar comparaciones cuantitativas.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *