Как я могу разобрать числа в скобках в списке строк на отрицательные числа (или строки с отрицательным знаком).
пример
input
list1= ['abcd','(1,234)','Level-2 (2):','(31)%', 'others','(3,102.2)%']
output
['abcd',-1234,'Level-2 (2):','-31%', 'others','-3102.2%']
должны анализироваться строки только с числами в скобках или числами с запятой/точкой внутри скобок, за которыми следует знак процента (%). другие строки, такие как 'Level-2 (2):'
, не должны анализироваться.
я пытался
translator = str.maketrans(dict.fromkeys('(),'))
['-'+(x.translate(translator)) for x in list1]
но вывод (к каждому элементу добавлен -
)
['-abcd', '-1234', '-Level-2 2:', '-31%', '-others', '-3102.2%']
@JonClements, эти строки являются ссылками на некоторые уровни, а не фактическими отрицательными числами.
Хорошо... но откуда синтаксический анализатор должен знать об этом... тогда он не может просто брать числа в скобках... - правила должны быть лучше определены... При каких обстоятельствах что-то (number)
может стать -number
и когда нет?
И как (1234) изменилось на -123?
@Devesh опечатка, я думаю ... так же, как (31.2)%
стало -3102.2%
:)
извините, поправил ввод/вывод. @JonClements следует анализировать только отрицательные числа / проценты, т. Е. a(2)
должно оставаться a(2)
, а (32)
должно быть -32
for item in list1:
idx = list1.index(item)
list1[idx] = '-' + list1[idx].replace('(','').replace(')','').replace(',','')
print (list1)
выход:
['-abcd', '-1234', '-Level-2 2:', '-31%', '-others', '-3102.2%']
или просто:
list1= ['abcd','(1,234)','Level-2 (2):','(31)%', 'others','(3,102.2)%']
print (['-' + item.replace('(','').replace(')','').replace(',','') for item in list1])
выход:
['-abcd', '-1234', '-Level-2 2:', '-31%', '-others', '-3102.2%']
Level-2 (2):
не следует изменять. следует анализировать только фактические отрицательные числа или отрицательные проценты.
Попробуйте использовать re.match
Бывший:
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)
Выход:
['abcd', '-1,234', 'Level-2 (2):', '-31%', 'others', '-31.2%']
Обновление согласно комментарию
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)
Выход:
['abcd', '-1234', 'Level-2 (2):', '-31%', 'others', '-3102.2%']
это не для (3,102.2)%
О .. не видел нового редактирования в вопросе .. Обновленный ответ
Вы можете попробовать использовать re.sub
, например:
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%']
как я могу удалить комы также
@Shijith, если вы не собираетесь использовать настоящие запятые в других строках, тогда вы можете просто добавить .replace(',', '')
в левый конец list-comp, в противном случае ... вы, вероятно, захотите применить его только к измененным строкам.
@jonClements спасибо, но это не для Level-2, (2):
получил это с небольшим изменением моего исходного кода translator = str.maketrans(dict.fromkeys('(),')) ['-'+(x.translate(translator)) if re.match(r'^\(([\d+.,]+)\)(%?)$', x) else x for x in list1]
. Спасибо всем за помощь
Если вам не нужно преобразовывать значение в int или float, re.match
и str.translate
должны помочь:
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]
Это дает:
['abcd', '-1234', 'Level-2 (2):', '-31%', 'others', '-3102.2%']
Есть ли причина, по которой
Level-2 (2)
не становитсяLevel-2 -2
?