如何在Python中将含点和逗号的字符串转换为浮点数
我想知道怎么把像 123,456.908
这样的字符串转换成浮点数 123456.908
在Python里该怎么做?
如果你想把字符串转换成整数,可以看看这个链接:如果字符串里有逗号作为千位分隔符,怎么把它转换成数字?,不过方法基本上是一样的。
10 个回答
如果你不知道地区设置(locale),但想要解析任何类型的数字,可以使用这个 parseNumber(text)
函数(在我的代码库里)。这个函数虽然不是完美的,但能考虑到大多数情况:
>>> 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
使用本地化服务
默认语言环境
标准库中的 locale
模块是 Python 用来和 C 语言本地化功能对接的工具。
基本用法是:
import locale
locale.atof('123,456')
在一些地方,,
被当作千位分隔符,这样会返回 123456.0
; 而在另一些地方,它被当作小数点,这样会返回 123.456
。
不过,默认情况下,这个是无法工作的:
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'
这是因为默认情况下,程序的语言环境和代码运行的平台没有关系,而是由 POSIX 标准定义的。文档中解释说:
程序启动时,语言环境是
C
语言环境,无论用户的首选语言环境是什么。唯一的例外是:在启动时,LC_CTYPE
类别会被更改,以设置当前语言环境编码为用户的首选编码。程序必须明确表示希望使用用户的首选语言环境设置,方法是调用setlocale(LC_ALL, '')
。
也就是说:除了记录系统默认的文本文件字符编码设置(现在通常是 UTF-8),默认情况下,locale
模块会以 Python 自身的方式来解释数据(使用一个叫 C
的语言环境,来源于 C 语言)。locale.atof
的功能和 float
处理字符串时是一样的,locale.atoi
也会模仿 int
。
使用环境中的语言环境
调用上面文档中提到的 setlocale
可以从用户的环境中获取语言环境设置。因此:
>>> 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
语言环境不会在意千位分隔符是否放在正确的位置 - 它只会识别并过滤它们:
>>> locale.atof('12,34,56.789')
123456.789
在 3.6 及以上版本中,它也不会在意下划线,这些是由内置的 float
和 int
转换单独处理的:
>>> locale.atof('12_34_56.789')
123456.789
另一方面,字符串的 format
方法和 f-strings 在使用 n
格式时是会考虑语言环境的:
>>> f'{123456.789:.9n}' # `.9` specifies 9 significant figures
'123,456.789'
如果没有之前的 setlocale
调用,输出中就不会有逗号。
显式设置语言环境
也可以临时设置语言环境,使用合适的语言环境名称,并将这些设置仅应用于本地化的特定方面。例如,如果只想对数字进行本地化解析和格式化,可以在 setlocale
调用中使用 LC_NUMERIC
而不是 LC_ALL
。
以下是一些示例:
>>> # 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'
所需的语言环境字符串 可能依赖于你的操作系统,并且 可能需要额外的工作来启用。
要恢复 Python 的默认行为,可以使用之前提到的 C
语言环境,方法是:locale.setlocale(locale.LC_ALL, 'C')
。
注意事项
设置语言环境会全局影响程序的行为,并且不是线程安全的。如果要设置,通常应该在程序开始时只做一次。再次引用文档:
在某些库例程中调用
setlocale()
通常是个坏主意,因为它会影响整个程序。保存和恢复语言环境几乎同样糟糕:这会消耗资源,并影响在设置恢复之前恰好运行的其他线程。
如果在为通用使用编写模块时,需要一个不受语言环境影响的操作版本(比如某些与
time.strftime()
相关的格式),你需要找到不使用标准库例程的方法。更好的做法是说服自己使用语言环境设置是可以的。只有在最后的情况下,才应该记录你的模块不兼容非C
语言环境设置。
当 Python 代码嵌入到 C 程序中时,设置语言环境 甚至可以影响 C 代码:
扩展模块不应该调用
setlocale()
,除非是为了找出当前的语言环境是什么。但由于返回值只能用于恢复语言环境,这并不是很有用(除了可能用来判断语言环境是否为C
)。
(注意:当 setlocale
只用一个 category
参数调用,或者用 None
- 而不是 空字符串 - 作为语言环境名称时,它不会改变任何东西,只会返回现有语言环境的名称。)
因此,这不是一个工具,用于在生产代码中实验解析或格式化本应适用于不同语言环境的数据。上面的例子只是为了说明系统是如何工作的。为此,建议寻找第三方国际化库。
不过,如果数据都是按照特定语言环境格式化的,提前指定该语言环境将使得可以使用 locale.atoi
和 locale.atof
作为 int
和 float
调用字符串输入的替代品。
只需要用 replace()
方法把 ,
去掉就可以了:
float("123,456.908".replace(',',''))