Shijith
Shijith

Reputation: 4882

parse parenthesized numbers to negative numbers

How can i Parse parenthesized numbers in a list of strings to negative numbers (or strings with negative sign).

example

input  
list1= ['abcd','(1,234)','Level-2 (2):','(31)%', 'others','(3,102.2)%']  

output  
['abcd',-1234,'Level-2 (2):','-31%', 'others','-3102.2%']

strings only with numbers inside parenthesis or numbers with comma/dot inside parenthesis followed by a percentage(%) sign, should be parsed . other strings such as 'Level-2 (2):' should not be parsed.

I have tried

translator = str.maketrans(dict.fromkeys('(),'))
['-'+(x.translate(translator)) for x in list1]

but the output is (every element has a - appended)

['-abcd', '-1234', '-Level-2 2:', '-31%', '-others', '-3102.2%']

Upvotes: 1

Views: 81

Answers (4)

Rakesh
Rakesh

Reputation: 82785

Try using re.match

Ex:

import re

list1= ['abcd','(1,234)','Level-2 (2):','(31)%', 'others','(31.2)%']  
result = []
for i in list1:
    m = re.match(r"\((\d+[.,]?\d*)\)(%?)", i) 
    if m:
        result.append("-" + m.group(1)+m.group(2))
    else:
        result.append(i)
print(result)

Output:

['abcd', '-1,234', 'Level-2 (2):', '-31%', 'others', '-31.2%']

Update as per comment

import re

list1 = ['abcd','(1,234)','Level-2 (2):','(31)%', 'others','(3,102.2)%']  
result = []
for i in list1:
    m = re.match(r"\((\d+(?:,\d+)*(?:\.\d+)?)\)(%?)", i) 
    if m:
        result.append("-" + m.group(1).replace(",", "")+m.group(2))
    else:
        result.append(i)
print(result)

Output:

['abcd', '-1234', 'Level-2 (2):', '-31%', 'others', '-3102.2%']

Upvotes: 2

ncica
ncica

Reputation: 7206

for item in list1:
    idx = list1.index(item)
    list1[idx] = '-' + list1[idx].replace('(','').replace(')','').replace(',','')

print (list1)

output:

['-abcd', '-1234', '-Level-2 2:', '-31%', '-others', '-3102.2%']

or just:

list1= ['abcd','(1,234)','Level-2 (2):','(31)%', 'others','(3,102.2)%']

print (['-' + item.replace('(','').replace(')','').replace(',','') for item in list1])

output:

['-abcd', '-1234', '-Level-2 2:', '-31%', '-others', '-3102.2%']

Upvotes: 0

Serge Ballesta
Serge Ballesta

Reputation: 149095

If you do not need to convert the value to int or float, re.match and str.translate should do the trick:

rx = re.compile('\([\d,.]+\)%?$')
tab = str.maketrans({i: None for i in '(),'})

output = ['-' + i.translate(tab) if rx.match(i) else i for i in list1]

It gives:

['abcd', '-1234', 'Level-2 (2):', '-31%', 'others', '-3102.2%']

Upvotes: 1

Jon Clements
Jon Clements

Reputation: 142216

You can try using re.sub, eg:

import re

list1 = ['abcd','(1,234)','Level-2 (2):','(31)%', 'others','(3,102.2)%']
res = [re.sub(r'^\(([\d+.,]+)\)(%?)$', r'-\1\2', el) for el in list1] 
# ['abcd', '-1,234', 'Level-2 (2):', '-31%', 'others', '-3,102.2%']

Upvotes: 4

Related Questions