Как преобразовать строку в число, если в ней есть запятые в качестве разделителей тысяч?

85

У меня есть строка, представляющая число, в котором для разделения тысяч используются запятые. Как я могу преобразовать это в число в Python?

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

Создает ValueError.

Я мог бы заменить запятые пустыми строками, прежде чем пытаться преобразовать их, но это почему-то кажется неправильным. Есть ли способ лучше?

дсимард
источник

Ответы:

103
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
Unutbu
источник
9
+1, но, пожалуйста, добавьте настройку локали (с локалью по умолчанию для 'C'этого все равно будет ValueError!).
Alex Martelli
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
локальную
40

Есть несколько способов разобрать числа с разделителями тысяч. И я сомневаюсь, что способ, описанный @unutbu, лучший во всех случаях. Поэтому я перечисляю и другие способы.

  1. Правильное место для вызова setlocale()находится в __main__модуле. Это глобальная настройка, которая повлияет на всю программу и даже расширения C (хотя обратите внимание, что настройка LC_NUMERIC не установлена ​​на системном уровне, а эмулируется Python). Прочтите предостережения в документации и дважды подумайте, прежде чем идти этим путем. Возможно, это нормально для отдельного приложения, но никогда не используйте его в библиотеках для широкой аудитории. Вероятно, вам следует избегать запроса локали с какой-либо конкретной кодировкой, поскольку она может быть недоступна в некоторых системах.

  2. Используйте одну из сторонних библиотек для интернационализации. Например, PyICU позволяет использовать любую доступную локаль без влияния на весь процесс (и даже анализировать числа с определенными разделителями тысяч без использования локалей):

    NumberFormat.createInstance (Locale ('en_US')). Parse ("1000000"). GetLong ()

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

Денис Откидач
источник
1
+1 за рекомендацию простого способа. Это все, что мне было нужно, когда у меня была такая же проблема.
Майкл Кристофик
Отредактировано для исправления опечатки ( setlocateдолжно быть setlocale). Также +1.
Марк Дикинсон
Бесстыдная самореклама, я все же воспользовалась третьим вариантом. Так что, если кому-то интересно, взгляните на этот вопрос / ответ
янв.
14

Замените запятые пустыми строками и превратите полученную строку в символ intили float.

>>> a = '1,000,000'
>>> int(a.replace(',' , ''))
1000000
>>> float(a.replace(',' , ''))
1000000.0
Коди Пирсолл
источник
21
Пожалуйста, прочтите еще раз вопрос OP. В частности, где он говорит: «Я мог бы заменить запятые пустыми строками, прежде чем пытаться преобразовать их, но это почему-то кажется неправильным. Есть ли лучший способ?»
Joaquin
1
Я нашел этот ответ полезным, учитывая, что у меня почти те же требования, что и у OP (преобразование strs в int), но я рад, что у меня есть более простой способ, чем принятый ответ.
Cai
4

Это работает:

(Грязный, но быстрый способ)

>>> a='-1,234,567,89.0123'
>>> "".join(a.split(","))
'-123456789.0123'
Wizmann
источник
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

Я пробовал это. Это выходит за рамки вопроса: вы получаете ввод. Сначала он будет преобразован в строку (если это список, например из Beautiful soup); затем в int, затем в float.

Он идет так далеко, как только может. В худшем случае он возвращает все не преобразованное в виде строки.

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