Как разбить произвольное математическое выражение на его множители

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

Например:

"((a*b>0) * (e>500)) * (abs(j)>2.0) * (n>1)"

Должен вернуться:

['a*b>0', 'e>500', 'abs(j)>2.0', 'n>1']

Если используется деление, все становится еще сложнее, но предположим для начала, что деления нет. Каким был бы самый пифонический способ решить эту проблему?


person greyxray    schedule 04.08.2017    source источник
comment
Каждая часть изолирована скобками?   -  person Willem Van Onsem    schedule 04.08.2017
comment
Что вы сделали с тех пор? Вы столкнулись с какой-либо конкретной проблемой?   -  person araknoid    schedule 04.08.2017
comment
@WillemVanOnsem, нет, но в случае, если входная строка будет (ab)›cd, вывод должен быть ['(ab)›cd'] или [' аb›cd']   -  person greyxray    schedule 04.08.2017


Ответы (3)


Вы можете просто использовать функцию split():

ans_list = your_string.split(" * ")

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

person Cuber    schedule 04.08.2017
comment
Это также разделит внутренний множитель: ['((a', 'b>0) ', ' (e>500)) ', ' (abs(j)>2.0) ', ' (n>1)']. - person Willem Van Onsem; 04.08.2017
comment
Исправлено, по крайней мере, для примера, который дал OP - person Cuber; 04.08.2017
comment
@pCube Вы предполагаете, что внутренний множитель не обернут пробелами... - person araknoid; 04.08.2017
comment
@pCube: честно говоря, я не думаю, что это действительно решает проблему. Исходя из вопроса, пользователь, вероятно, может ввести произвольное выражение. Таким образом, он/она может ввести (a * b)*c. Который разделит внутренний и не разделит внешний. - person Willem Van Onsem; 04.08.2017
comment
Согласен с частью слишком многих предположений. Но это работает для примера ОП. Я могу попытаться придумать более общее решение, если это необходимо. - person Cuber; 04.08.2017
comment
@WillemVanOnsem Я думаю, что потребуются некоторые произвольные требования к разделению, в настоящее время выражение OP разделено на несколько уровней в дереве синтаксического анализа, оператор, разделенный пробелами, кажется таким же произвольным, как выражения в квадратных скобках. - person AChampion; 04.08.2017

вы можете использовать регулярное выражение:

s = "((a*b>0) * (e>500)) * (abs(j)>2.0) * (n>1)"
s = ''.join(s.split())
s = re.split(r'([\)]+[\*\+\-/\^]+[\(])', s)
res = []
for x in s:
    x = re.sub(r'(^[\(\)\*\+\-\/]+)', '', x)
    x = re.sub(r'([\(\)]+$)', '', x)
    if len(x) > 0: res.append(x)
print(res)
person nguyen thanh chinh    schedule 04.08.2017
comment
Ответы на регулярное выражение более полезны, если вы объясните, как работает регулярное выражение. - person skrrgwasme; 04.08.2017
comment
Сначала я разделил s на '[)]+*[(]+', затем удалил некоторые '(' в начале или ')' в конце строки - person nguyen thanh chinh; 04.08.2017
comment
@nguyenthanhchinh, контрпример "((a*b>c) - (a*b>c))" даст ['a*b>c)-(a*b>c'] - person greyxray; 04.08.2017
comment
@greyxrar, я только что исправил ответ, надеюсь, это поможет - person nguyen thanh chinh; 04.08.2017
comment
@nguyenthanhchinh Вы должны отредактировать свой ответ, включив объяснение, а не оставлять его в комментариях. - person skrrgwasme; 04.08.2017

person    schedule
comment
((a*b>c)-(a*b>c)) этот пример выдаст ['ab›c', 'ab›c'] - person greyxray; 07.08.2017
comment
@greyxray, когда я запускаю свою программу, этот пример работает нормально, проверьте еще раз. Выход: ['a*b>c', 'a*b>c'] - person Gadolfo; 07.08.2017
comment
но это не разбиение на множители, это операция вычитания - person greyxray; 09.08.2017