Pythonic方法将表达式中的运算符和操作数分开

时间:2012-09-22 21:42:29

标签: python

我试图将运算符(包括括号)和表达式中的操作数分开。例如,给出一个表达式

expr = "(32+54)*342-(4*(3-9))"

我想要

['(', '32', '+', '54', ')', '*', '342', '-', '(', '4', '*', '(', '3', '-', '9', ')', ')']

这是我写的代码。有没有更好的方法在python中做到这一点。

l = list(expr)
n = ''
expr = []
try:
  for c in l:
    if c in string.digits:
      n += c
    else:
      if n != '':
        expr.append(n)
        n = ''
      expr.append(c)
finally:
  if n != '':
    expr.append(n)

4 个答案:

答案 0 :(得分:3)

我们可以使用re.split()执行此操作:

>>> import re
>>> expr = "(32+54)*342-(4*(3-9))"
>>> re.split("([-()+*/])", expr)
['', '(', '32', '+', '54', ')', '', '*', '342', '-', '', '(', '4', '*', '', '(', '3', '-', '9', ')', '', ')', '']

这会插入一些空字符串,但这些字符串可能很容易被处理或删除。例如,list comprehension

>>> [part for part in re.split("([-()+*/])", expr) if part]
['(', '32', '+', '54', ')', '*', '342', '-', '(', '4', '*', '(', '3', '-', '9', ')', ')']

答案 1 :(得分:1)

如果您只是想对流进行标记,那么您的方法很好,但有点过时了。您可以使用regular expression更轻松地拆分令牌。

但是,如果你还想对标记做一些事情(比如评估它们),那么我建议你看一个可以处理递归的解析模块(正则表达式不能处理递归),比如pyparsing

答案 2 :(得分:1)

Python:Batteries Included

>>> [x[1] for x in tokenize.generate_tokens(StringIO.StringIO('(32+54)*342-(4*(3-9))').readline)]
['(', '32', '+', '54', ')', '*', '342', '-', '(', '4', '*', '(', '3', '-', '9', ')', ')', '']

答案 3 :(得分:0)

>>> if True:
    exp=[]
    expr = "(32+54)*342-(4*(3-9))"
    flag=False
    for i in expr:
        if i.isdigit() and flag:
            exp.append(str(exp.pop(len(exp)-1))+i)
        elif i.isdigit():
            flag=True
            exp.append(i)
        else:
            flag=False
            exp.append(i)
    print(exp)


['(', '32', '+', '54', ')', '*', '342', '-', '(', '4', '*', '(', '3', '-', '9', ')', ')']
>>>