自定义语言环境配置以进行浮点转换 [英] Custom locale configuration for float conversion

查看:48
本文介绍了自定义语言环境配置以进行浮点转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将格式为"1.234.345,00" 的字符串转换为 float 1234345.00 .

I need to convert a string in the format "1.234.345,00" to the float value 1234345.00.

一种方法是使用重复的 str.replace :

One way is to use repeated str.replace:

x = "1.234.345,00"
res = float(x.replace('.', '').replace(',', '.'))

print(res, type(res))
1234345.0 <class 'float'>

但是,这似乎是手动的和非通用的.这个被强烈推荐的答案建议使用 locale 库.但是我的默认语言环境与输入字符串没有相同的约定.然后,我发现了一种将本地约定中使用的字符提取为字典的方法:

However, this appears manual and non-generalised. This heavily upvoted answer suggests using the locale library. But my default locale doesn't have the same conventions as my input string. I then discovered a way to extract the characters used in local conventions as a dictionary:

import locale

print(locale.localeconv())

{'int_curr_symbol': '', 'currency_symbol': '', 'mon_decimal_point': '',
 ..., 'decimal_point': '.', 'thousands_sep': '', 'grouping': []}

是否有一种方法可以更新此字典,另存为自定义语言环境,然后可以调用此自定义语言环境.像这样:

Is there a way to update this dictionary, save as a custom locale and then be able to call this custom locale going forwards. Something like:

mylocale = locale.create_new_locale()  # "blank" conventions or copied from default
mylocale.localeconv()['thousands_sep'] = '.'
mylocale.localeconv()['decimal_point'] = ','

setlocale(LC_NUMERIC, mylocale)
atof('123.456,78')  # 123456.78

如果这不可能,我们如何获得所有可用语言环境及其约定的列表?似乎反模式可以根据惯例推论"正确的配置(更不用说效率低下的手册了),所以我希望有一个通用的解决方案,例如上面的伪代码.

If this isn't possible, how do we get a list of all available locale and their conventions? Seems anti-pattern to "deduce" the correct configuration from the conventions (not to mention inefficient / manual), so I was hoping for a generic solution such as above pseudo-code.

这是我尝试查找 thousands_sep =='.' decimal_point ==','的所有语言环境的尝试.实际上,更普遍的是,通过以下参数的组合对语言环境进行分组:

Here's my attempt at finding all locales where thousands_sep == '.' and decimal_point == ','. In fact, more generally, to group locales by combinations of these parameters:

import locale
from collections import defaultdict

d = defaultdict(list)

for alias in locale.locale_alias:
    locale.setlocale(locale.LC_ALL, alias)
    env = locale.localeconv()
    d[(env['thousands_sep'], env['decimal_point'])].append(alias)

结果:

---------------------------------------------------------------------------
Error                                     Traceback (most recent call last)
<ipython-input-164-f8f6a6db7637> in <module>()
      5 
      6 for alias in locale.locale_alias:
----> 7     locale.setlocale(locale.LC_ALL, alias)
      8     env = locale.localeconv()
      9     d[(env['thousands_sep'], env['decimal_point'])].append(alias)

C:\Program Files\Anaconda3\lib\locale.py in setlocale(category, locale)
    596         # convert to string
    597         locale = normalize(_build_localename(locale))
--> 598     return _setlocale(category, locale)
    599 
    600 def resetlocale(category=LC_ALL):

Error: unsupported locale setting

推荐答案

如果您弹出区域设置的源代码,您会看到有一个名为 _override_localeconv 的变量(似乎是针对测试目的).

If you pop open the source code for locale, you can see that there is a variable called _override_localeconv (which seems to be for testing purposes).

# With this dict, you can override some items of localeconv's return value.
# This is useful for testing purposes.
_override_localeconv = {}

尝试以下操作似乎确实会覆盖字典,而不更改整个语言环境,尽管这可能会带来一些意想不到的后果,尤其是因为更改语言环境不是线程安全的.小心!

Trying the following does seem to override the dictionary without changing the entire locale, though it probably has some unintended consequences, especially since changing locales isn't threadsafe. Be careful!

import locale

locale._override_localeconv["thousands_sep"] = "."
locale._override_localeconv["decimal_point"] = ","

print locale.atof('123.456,78')

在线试玩!

这篇关于自定义语言环境配置以进行浮点转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆