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


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

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'

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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.