lvi
lvi

Reputation: 159

A list of lists from string in Python

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

Answers (3)

Guy Gavriely
Guy Gavriely

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

HYRY
HYRY

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

user2357112
user2357112

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.

  • If you see a number, call int or float on it and return the result.
  • If you see something that isn't a number or a parenthesis, just return it as a string.
  • If you see an opening parenthesis, recursively parse objects from the token sequence and add them to a list until you see a closing parenthesis. Return the list.

Upvotes: 2

Related Questions