1

У меня есть строка, как '$200,000,000' или 'Yan300,000,000'Python эффективно разделить знак валюты и номер в одной строке

Я хочу, чтобы разделить валюту и номер, а выход кортеж ('$', '200000000'), без ',' в строке чисел.

В настоящее время я использую следующий скрипт, который работает:

def splitCurrency(cur_str): 
    cuttingIdx = 0 
    for char in cur_str: 
     try: 
      int(char) 
      break 
     except ValueError: 
      cuttingIdx = cuttingIdx + 1 
    return (cur_str[0:cuttingIdx].strip(), 
      cur_str[cuttingIdx:len(cur_str)].replace(',','')) 

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

ответ

3
>>> import re 
>>> string = 'YAN300,000,000' 
>>> match = re.search(r'([\D]+)([\d,]+)', string) 
>>> output = (match.group(1), match.group(2).replace(',','')) 
>>> output 
('YAN', '300000000') 

(Благодаря zhangyangyu за указание я не полностью ответил на вопрос)

+2

ОП не хочет, чтобы номер «,» в номере. Ваше решение не является полным. – zhangyangyu

+0

Спасибо, ваше решение выглядит наиболее читаемым для меня :) – Mai

0
>>> import itertools 
>>> myStr = '$200,000,000' 
>>> ''.join(itertools.dropwhile(lambda c: not c.isdigit(), myStr)) 
'200,000,000' 
>>> myStr = 'Yan300,000,000' 
>>> ''.join(itertools.dropwhile(lambda c: not c.isdigit(), myStr)) 
'300,000,000' 

Кроме того, вы можете использовать itertools.takewhile с той же lambda функции, чтобы получить знак валюты. Тем не менее, это может быть проще:

idx = itertools.dropwhile(lambda c: not c.isdigit()).next() 
sign, val = myStr[:idx], myStr[idx:] 
+0

Благодарим за решение. – Mai

0

Это обыкновение быть быстрее, я держал пари ... но я думаю, что его более читаемым

>>> cur_string = "asd1,23456,123,1233" 
>>> cur_sym = re.search(r"([^0-9, ]*)[0-9]","asd123").groups()[0] 
>>> cur = re.sub("[^0-9]","",cur_string) 
>>> print cur_sym,int(cur) 
asd 1234561231233 
+0

Спасибо! Это определенно более читаемо, чем мое. – Mai

1
>>> filter(str.isdigit, s) 
'200000000' 
>>> filter(lambda x: not x.isdigit() and x != ',', s) 
'$' 
>>> 
>>> (filter(lambda x: not x.isdigit() and x != ',' ,s), filter(str.isdigit, s)) 
('$', '200000000') 
>>> 
+0

Благодарим вас за предложение. Интересный подход. – Mai

1
import locale 
import re 
locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') 

def split_currency(text): 
    _, currency, num = re.split('^(\D+)', text, 1) 
    num = locale.atoi(num) 
    return currency, num 
print(split_currency('$200,000,000')) 
# ('$', 200000000) 
print(split_currency('Yan300,000,000')) 
# ('Yan', 300000000) 

split_currency поднимет значение ValueError, если text не начинается с символа валюты (или всего, что не является цифрой). Вы можете использовать try...except для обработки этого случая по-другому, если хотите.

+0

Благодарим вас за предложение. Я хочу избежать любой попытки, кроме производительности, поскольку я запускаю ее на больших данных. – Mai

0

Вы можете использовать регулярное выражение для этого.

p1 = re.compile("\d") #match digits 
p2 = re.compile("\D") match non-digits 


currency_symbol = p1.split(cur_str)[0] 
value = int("".join([group for group in p2.split(cur_str)])) 
+0

Я не уверен, что для этой задачи требуется объединение. – Mai