Как использовать Python для преобразования строки в число, если в нем есть запятые в качестве разделителей тысяч?
У меня есть строка, которая представляет число, которое использует запятые для разделения тысяч. Как я могу преобразовать это число в Python?
>>> int("1,000,000")
Создает ValueError
,
Я мог бы заменить запятые на пустые строки, прежде чем пытаться преобразовать их, но это как-то не так. Есть ли способ лучше?
12 ответов
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, является лучшим во всех случаях. Вот почему я перечисляю и другие способы.
Правильное место для вызова
setlocale()
в__main__
модуль. Это глобальная настройка, которая повлияет на всю программу и даже на расширения C (хотя обратите внимание, что настройка LC_NUMERIC не устанавливается на системном уровне, а эмулируется Python). Прочитайте предостережения в документации и дважды подумайте, прежде чем идти по этому пути. Это, вероятно, нормально в одном приложении, но никогда не используйте его в библиотеках для широкой аудитории. Возможно, вам следует избегать запроса локали с определенной кодировкой charset, поскольку она может быть недоступна в некоторых системах.Используйте одну из сторонних библиотек для интернационализации. Например, PyICU позволяет использовать любую доступную локаль без влияния на весь процесс (и даже анализировать числа с конкретными разделителями тысяч без использования локалей):
NumberFormat.createInstance (Locale ('en_US')). Синтаксический ("1000000"). GetLong()
Напишите свою собственную функцию синтаксического анализа, если вам не нужно устанавливать сторонние библиотеки, чтобы сделать это "правильно". Это может быть так просто, как
int(data.replace(',', ''))
когда строгая проверка не требуется.
Замените запятые пустыми строками и превратите полученную строку в int
или float
,
>>> a = '1,000,000'
>>> int(a.replace(',' , ''))
1000000
>>> float(a.replace(',' , ''))
1000000.0
Это работает:
(Грязный, но быстрый способ)
>>> a='-1,234,567,89.0123'
>>> "".join(a.split(","))
'-123456789.0123'
Я получил ошибку локали из принятого ответа, но в Финляндии работает следующее изменение (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
Самым питоническим решением будет int("1,000,000".replace(',', ''))
Но если вы не хотите использовать .replace() и, скажем, не хотите ничего импортировать.
string = '1,000,000,000'
# string_w_float = '1,000,000,000.5'
no_comma = ''
for num in string:
# if num == '.':
# break # own code here for after decimal
try:
no_comma += str(int(num))
except:
pass
print(int(no_comma))
Я попробовал это. Это выходит за рамки вопроса: вы получаете вход. Сначала он будет преобразован в строку (если это список, например, из Beautiful soup); затем 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
Немного поздно, но в библиотеке babel есть parse_decimal и parse_number , которые делают именно то, что вы хотите:
from babel.numbers import parse_decimal, parse_number
parse_decimal('10,3453', locale='es_ES')
>>> Decimal('10.3453')
parse_number('20.457', locale='es_ES')
>>> 20457
parse_decimal('10,3453', locale='es_MX')
>>> Decimal('103453')
Вы также можете передать класс Locale вместо строки:
from babel import Locale
parse_decimal('10,3453', locale=Locale('es_MX'))
>>> Decimal('103453')
Не самое короткое решение, но для полноты картины и, возможно, интересно, если вы хотите положиться на существующую функцию, проверенную миллион раз: вы можете использовать pandas , введя свой номер в виде StringIO в ееread_csv()
(у него есть серверная часть C, поэтому функциональность преобразования не может быть использована напрямую - насколько мне известно).
>>> float(pd.read_csv(StringIO("1,000.23"), sep=";", thousands=",", header=None)[0])
1000.23
Если вы используетеpandas
и вы пытаетесь разобрать CSV, который включает числа с запятой для разделителей тысяч, вы можете просто передать аргумент ключевого словаthousands=','
вот так:
df = pd.read_csv('your_file.csv', thousands=',')
>>> 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 в США. -Suresh
#python3 tenzin
def changenum(data):
foo = ""
for i in list(data):
if i == ",":
continue
else:
foo += i
return float(int(foo))