Reputation: 159
I need a method that makes a list from a string like following:
"( * 1 2 ( - 4 3 ) )" -> ["*", 1, 2, ["-", 4, 3]]
Is there any simple way to handle this problem?
Upvotes: 2
Views: 124
Reputation: 11396
use pyparsing, like:
from pyparsing import *
enclosed = Forward()
nestedParens = nestedExpr('(', ')', content=enclosed)
integer = Word( nums ) # simple unsigned integer
arithOp = Word( "+-*/", max=1 ) # arithmetic operators
enclosed << ( nestedParens | arithOp | integer )
data = '( * 1 2 ( - 4 3 ) )'
print enclosed.parseString(data).asList()
output:
$ python parse.py
[['*', '1', '2', ['-', '4', '3']]]
Upvotes: 3
Reputation: 97291
Some thing like this:
a = " ( * 1 2 ( - 4 35 ) ( + 100 ( / 1 2 ) ) ( + 100 200 ) )"
def p(s):
r = []
for x in s:
if x == "(":
r.append( p(s) )
elif x == ")":
return r
else:
r.append(x)
return r
p(iter(a.split()))
the output is:
Out[23]:
[['*',
'1',
'2',
['-', '4', '35'],
['+', '100', ['/', '1', '2']],
['+', '100', '200']]]
You need add some code to convert string to number.
Upvotes: 3
Reputation: 280778
There's no simple built-in to call or one-liner trick you can use, but it's still entirely manageable.
First, you'll want to tokenize the input. Roughly speaking, that means separating it into units like (
, *
, and 123
. If your input is guaranteed to be space-separated, you can just use the split
method, but if you need to handle input like (* (+ 1 2) 3)
, it could be a bit harder.
>>> "( * 1 2 ( - 4 3 ) )".split()
['(', '*', '1', '2', '(', '-', '4', '3', ')', ')']
Now that you have a sequence of tokens, we can write a recursive parser. Go over the tokens one at a time.
int
or float
on it and return the result.Upvotes: 2