Як перетворити рядок у число, якщо в ньому є коми як тисячні роздільники?


84

У мене є рядок, який представляє число, яке використовує коми для розділення тисяч. Як я можу перетворити це на число в python?

>>> int("1,000,000")

Генерує a ValueError.

Я міг замінити коми порожніми рядками, перш ніж спробувати перетворити їх, але це якось неправильно. Чи є кращий спосіб?

Відповіді:


102
import locale
locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' ) 
locale.atoi('1,000,000')
# 1000000
locale.atof('1,000,000.53')
# 1000000.53

9
+1, але, будь-ласка, додайте налаштування мови (з мовою за замовчуванням 'C'це все одно дасть ValueError!).
Алекс Мартеллі,

1
Я думаю, що гуру має на увазі щось подібне: locale.setlocale (locale.LC_ALL, 'en_US.UTF-8')
mbarkhau

Дякую за коментарі. Я додав конкретну мову.
unutbu

Дуже хороша. Таким чином я можу обробляти європейські номери, де також міняються коми та крапки. Дякую.
dsimard

5
Я отримую Traceback (most recent call last): File "F:\test\locale_num.py", line 2, in <module> locale.setlocale( locale.LC_ALL, 'en_US.UTF-8' ) File "F:\Python27\lib\locale.py", line 539, in setlocale return _setlocale(category, locale) locale.Error: unsupported locale setting
локальну

39

Існує кілька способів синтаксичного аналізу чисел за допомогою тисяч роздільників. І я сумніваюся, що спосіб, описаний @unutbu, є найкращим у всіх випадках. Тому я перелічую й інші шляхи.

  1. Правильне місце для дзвінка setlocale()- в __main__модулі. Це глобальне налаштування, яке вплине на всю програму і навіть розширення C (хоча зверніть увагу, що налаштування LC_NUMERIC не встановлено на системному рівні, а емулюється Python). Прочитайте застереження в документації і добре подумайте, перш ніж піти цим шляхом. Можливо, це нормально в одному додатку, але ніколи не використовуйте його в бібліотеках для широкої аудиторії. Ймовірно, вам слід уникати запиту локалі з певним кодуванням набору символів, оскільки він може бути недоступний у деяких системах.

  2. Використовуйте одну з сторонніх бібліотек для інтернаціоналізації. Наприклад, PyICU дозволяє використовувати будь-яку доступну локаль, що впливає на весь процес (і навіть синтаксичний аналіз чисел за допомогою окремих тисяч роздільників без використання локалей):

    NumberFormat.createInstance (Locale ('en_US')). Parse ("1,000,000"). GetLong ()

  3. Напишіть власну функцію синтаксичного аналізу, якщо ви не знаєте, що встановлювати сторонні бібліотеки, щоб робити це "правильно". Це може бути настільки просто, як int(data.replace(',', ''))тоді, коли не потрібна сувора перевірка.


1
+1 за рекомендацію простого способу. Це все, що мені потрібно було, коли у мене була така сама проблема.
Michael Kristofik

Відредаговано для виправлення друкарської помилки ( setlocateмає бути setlocale). Також +1.
Марк Дікінсон,

Безсоромна самореклама, я таки використав третій варіант. Тож, якщо комусь цікаво, подивіться на це питання / відповідь
січня

13

Замініть коми кодами порожніми рядками, а отриманий рядок перетворіть на intабо a float.

>>> a = '1,000,000'
>>> int(a.replace(',' , ''))
1000000
>>> float(a.replace(',' , ''))
1000000.0

21
Будь ласка, прочитайте ще раз питання OP. Зокрема, там, де він каже: "Я міг замінити коми порожніми рядками, перш ніж спробувати перетворити їх, але це якось не так. Чи є кращий спосіб?"
Хоакін

1
Я знайшов цю відповідь корисною, враховуючи те, що я маю майже ті самі вимоги, що і OP (перетворити strs на ints), але я радий мати простіший спосіб, ніж прийнята відповідь.
Цай

4

Це працює:

(Брудний, але швидкий спосіб)

>>> a='-1,234,567,89.0123'
>>> "".join(a.split(","))
'-123456789.0123'

3

Я отримав локальну помилку від прийнятої відповіді, але така зміна працює тут, у Фінляндії (Windows XP):

import locale
locale.setlocale( locale.LC_ALL, 'english_USA' )
print locale.atoi('1,000,000')
# 1000000
print locale.atof('1,000,000.53')
# 1000000.53

1

Я спробував це. Це трохи виходить за межі питання: Ви отримуєте введення. Спочатку він буде перетворений у рядок (якщо це список, наприклад з Гарний суп); то до int, то до плавання.

Це заходить так далеко, наскільки це можливо. У гіршому випадку він повертає все неперетворене як рядок.

def to_normal(soupCell):
''' converts a html cell from beautiful soup to text, then to int, then to float: as far as it gets.
US thousands separators are taken into account.
needs import locale'''

locale.setlocale( locale.LC_ALL, 'english_USA' ) 

output = unicode(soupCell.findAll(text=True)[0].string)
try: 
    return locale.atoi(output)
except ValueError: 
    try: return locale.atof(output)
    except ValueError:
        return output

0
>>> import locale
>>> locale.setlocale(locale.LC_ALL, "")
'en_US.UTF-8'
>>> print locale.atoi('1,000,000')
1000000
>>> print locale.atof('1,000,000.53')
1000000.53

це робиться на Linux в США.


-1
#python3 tenzin
def changenum(data):
    foo = ""
    for i in list(data):
        if i == ",":
            continue
        else:
            foo += i
    return  float(int(foo))

2
Якесь пояснення, щоб піти з цим кодом? Чашу супу зазвичай подають ложкою для супу
cs95,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.