¿Cómo puedo convertir una cadena con punto y coma en un flotante en Python?
¿Cómo puedo convertir una cadena como 123,456.908
para que flote 123456.908
en Python?
Para int
s, consulte ¿Cómo convertir una cadena en un número si tiene comas como separadores de miles? , aunque las técnicas son esencialmente las mismas.
Utilizar los servicios de localización
La configuración regional predeterminada
El locale
módulo de biblioteca estándar es la interfaz de Python para rutinas de localización basadas en C.
El uso básico es:
import locale
locale.atof('123,456')
En lugares donde ,
se trata como un separador de miles, esto devolvería 123456.0
; en lugares donde se trata como un punto decimal, devolverá 123.456
.
Sin embargo, de forma predeterminada, esto no funcionará :
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python3.8/locale.py", line 326, in atof
return func(delocalize(string))
ValueError: could not convert string to float: '123,456'
Esto se debe a que, de forma predeterminada, el programa está "en una configuración regional" que no tiene nada que ver con la plataforma en la que se ejecuta el código, sino que está definido por el estándar POSIX. Como explica la documentación:
Inicialmente, cuando se inicia un programa, la configuración regional es la
C
configuración regional, sin importar cuál sea la configuración regional preferida del usuario. Hay una excepción: laLC_CTYPE
categoría se cambia al inicio para establecer la codificación local actual en la codificación local preferida del usuario. El programa debe decir explícitamente que quiere la configuración regional preferida del usuario para otras categorías llamando asetlocale(LC_ALL, '')
.
Es decir: además de tomar nota de la configuración predeterminada del sistema para la codificación de caracteres preferida en archivos de texto (hoy en día, probablemente será UTF-8), de forma predeterminada, el locale
módulo interpretará los datos de la misma manera que lo hace el propio Python (a través de una configuración regional denominada C
, en honor al lenguaje de programación C). locale.atof
hará lo mismo que float
pasa una cadena, y de manera similar locale.atoi
imitará int
.
Usando una configuración regional del entorno
Al realizar la setlocale
llamada mencionada en la cita anterior de la documentación, se obtendrán las configuraciones locales del entorno del usuario. De este modo:
>>> import locale
>>> # passing an empty string asks for a locale configured on the
>>> # local machine; the return value indicates what that locale is.
>>> locale.setlocale(locale.LC_ALL, '')
'en_CA.UTF-8'
>>> locale.atof('123,456.789')
123456.789
>>> locale.atof('123456.789')
123456.789
A la configuración regional no le importará si los separadores de miles están en el lugar correcto; simplemente los reconoce y filtra:
>>> locale.atof('12,34,56.789')
123456.789
En 3.6 y versiones posteriores, tampoco le importarán los guiones bajos, que se manejan por separado mediante la conversión float
y la función integradaint
:
>>> locale.atof('12_34_56.789')
123456.789
Por otro lado, el format
método de cadena y las cadenas f tienen en cuenta la configuración regional si n
se utiliza el formato :
>>> f'{123456.789:.9n}' # `.9` specifies 9 significant figures
'123,456.789'
Sin la setlocale
llamada anterior, la salida no tendría la coma.
Establecer una ubicación explícitamente
También es posible realizar configuraciones regionales temporales, utilizando el nombre de configuración regional apropiado, y aplicar esas configuraciones solo a un aspecto específico de la localización. Para obtener análisis y formato localizados solo para números, por ejemplo, utilice LC_NUMERIC
en lugar de LC_ALL
en la setlocale
llamada.
Aquí hay unos ejemplos:
>>> # in Denmark, periods are thousands separators and commas are decimal points
>>> locale.setlocale(locale.LC_NUMERIC, 'en_DK.UTF-8')
'en_DK.UTF-8'
>>> locale.atof('123,456.789')
123.456789
>>> # Formatting a number according to the Indian lakh/crore system:
>>> locale.setlocale(locale.LC_NUMERIC, 'en_IN.UTF-8')
'en_IN.UTF-8'
>>> f'{123456.789:9.9n}'
'1,23,456.789'
Las cadenas de configuración regionales necesarias pueden depender de su sistema operativo y pueden requerir trabajo adicional para habilitarlas .
Para volver a cómo se comporta Python de forma predeterminada, utilice la C
configuración regional descrita anteriormente, así: locale.setlocale(locale.LC_ALL, 'C')
.
Advertencias
Configurar la configuración regional afecta el comportamiento del programa globalmente y no es seguro para subprocesos. Si se hace, normalmente debería hacerse sólo una vez al comienzo del programa. Nuevamente citando la documentación:
Generalmente es una mala idea llamar
setlocale()
a alguna rutina de la biblioteca, ya que como efecto secundario afecta a todo el programa. Guardarlo y restaurarlo es casi igual de malo: es costoso y afecta a otros subprocesos que se ejecutan antes de que se restablezca la configuración.
Si, al codificar un módulo para uso general, necesita una versión independiente de la configuración regional de una operación que se ve afectada por la configuración regional (como ciertos formatos utilizados con
time.strftime()
), tendrá que encontrar una manera de hacerlo sin utilizar la rutina de biblioteca estándar. . Aún mejor es convencerse de que usar la configuración local está bien. Sólo como último recurso debe documentar que su módulo no es compatible conC
configuraciones no locales.
Cuando el código Python está incrustado en un programa C, configurar la configuración regional puede incluso afectar el código C :
Los módulos de extensión nunca deben llamar a
setlocale()
, excepto para averiguar cuál es la configuración regional actual. Pero dado que el valor de retorno sólo se puede utilizar de forma portátil para restaurarlo, eso no es muy útil (excepto quizás para averiguar si la configuración regional esC
).
(NB: cuando setlocale
se llama con un solo category
argumento o con None
, no una cadena vacía, para el nombre de la configuración regional, no cambia nada y simplemente devuelve el nombre de la configuración regional existente).
Por lo tanto, esto no pretende ser una herramienta, en el código de producción, para intentar analizar o formatear experimentalmente datos destinados a diferentes configuraciones regionales. Los ejemplos anteriores son sólo ejemplos para ilustrar cómo funciona el sistema. Para ello, busque una biblioteca de internacionalización de terceros.
Sin embargo, si todos los datos están formateados de acuerdo con una configuración regional específica, especificar esa configuración regional con anticipación permitirá utilizar locale.atoi
y locale.atof
como reemplazos directos para int
llamadas float
en la entrada de cadenas.
Simplemente elimine ,
con replace()
:
float("123,456.908".replace(',',''))
Si no conoce la configuración regional y desea analizar cualquier tipo de número, use esta parseNumber(text)
función (Mi repositorio). No es perfecto pero tenga en cuenta la mayoría de los casos:
>>> parseNumber("a 125,00 €")
125
>>> parseNumber("100.000,000")
100000
>>> parseNumber("100 000,000")
100000
>>> parseNumber("100,000,000")
100000000
>>> parseNumber("100 000 000")
100000000
>>> parseNumber("100.001 001")
100.001
>>> parseNumber("$.3")
0.3
>>> parseNumber(".003")
0.003
>>> parseNumber(".003 55")
0.003
>>> parseNumber("3 005")
3005
>>> parseNumber("1.190,00 €")
1190
>>> parseNumber("1190,00 €")
1190
>>> parseNumber("1,190.00 €")
1190
>>> parseNumber("$1190.00")
1190
>>> parseNumber("$1 190.99")
1190.99
>>> parseNumber("1 000 000.3")
1000000.3
>>> parseNumber("1 0002,1.2")
10002.1
>>> parseNumber("")
>>> parseNumber(None)
>>> parseNumber(1)
1
>>> parseNumber(1.1)
1.1
>>> parseNumber("rrr1,.2o")
1
>>> parseNumber("rrr ,.o")
>>> parseNumber("rrr1rrr")
1