¿Cómo puedo convertir una cadena con punto y coma en un flotante en Python?

Resuelto kevinlu asked hace 13 años • 10 respuestas

¿Cómo puedo convertir una cadena como 123,456.908para que flote 123456.908en Python?


Para ints, 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.

kevinlu avatar Jul 09 '11 14:07 kevinlu
Aceptado

Utilizar los servicios de localización

La configuración regional predeterminada

El localemó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 Cconfiguración regional, sin importar cuál sea la configuración regional preferida del usuario. Hay una excepción: la LC_CTYPEcategorí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 a setlocale(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 localemó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.atofhará lo mismo que floatpasa una cadena, y de manera similar locale.atoiimitará int.

Usando una configuración regional del entorno

Al realizar la setlocalellamada 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 floaty la función integradaint :

>>> locale.atof('12_34_56.789')
123456.789

Por otro lado, el formatmétodo de cadena y las cadenas f tienen en cuenta la configuración regional si nse utiliza el formato :

>>> f'{123456.789:.9n}' # `.9` specifies 9 significant figures
'123,456.789'

Sin la setlocalellamada 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_NUMERICen lugar de LC_ALLen la setlocalellamada.

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 Cconfiguració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 con Cconfiguraciones 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 es C).

(NB: cuando setlocalese llama con un solo categoryargumento 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.atoiy locale.atofcomo reemplazos directos para intllamadas floaten la entrada de cadenas.

Karl Knechtel avatar Jul 09 '2011 09:07 Karl Knechtel

Simplemente elimine ,con replace():

float("123,456.908".replace(',',''))
Zach Kelling avatar Jul 09 '2011 08:07 Zach Kelling

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
hayj avatar Apr 24 '2018 14:04 hayj