3

I am trying to parse lisp input to python list. But when I parse the input I get list of strings but I want individual element as int.

Example: When I parse following input: "(2 (10 (5 11))) (5 6) (4)" Output: [[['2'], ['10', '5']], [['5'], ['6']], [['4']]]

I use: [[map(int, x) for x in lst] for lst in test] to convert the strings to int but this function will only parse nested list of level 2. But if I have a nested list of more than 2, how should I use it to parse?

I tried pyparsing but I didn't understand it properly.

2
  • 1
    Can you show the parsing code you used? The best solution will probably involve a change there rather than a post-processing step. Commented Sep 23, 2013 at 7:17
  • In pyparsing, you can attach a parse action to do the integer string-to-int conversion at parse time. Look at this example pyparsing.wikispaces.com/file/view/chemicalFormulas.py/31041705/… on the pyparsing wiki. See in the internal Version 2 of the parser, how the convertIntegers method is attached to the integer expression. This does the string-to-int conversion at parse time, rather than having to post-process later. Commented Sep 23, 2013 at 7:51

2 Answers 2

5
def as_int(xs):
    if isinstance(xs, list):
        return map(as_int, xs)
    elif isinstance(xs, str):
        return int(xs)
    return xs

Usage:

>>> xs = [[['2'], ['10', '5']], [['5'], ['6']], [['4']]]
>>> print as_int(xs)
[[[2], [10, 5]], [[5], [6]], [[4]]]
Sign up to request clarification or add additional context in comments.

Comments

3

If you want to use pyparsing, you could do so without any postprocessing as follows.

import pyparsing as pp

integer = pp.Word(pp.nums).setParseAction(lambda m:int(m[0]))
expr = pp.Forward()
expr << pp.nestedExpr(content=pp.OneOrMore(integer | expr))
manyExpr = pp.OneOrMore(expr)

print manyExpr.parseString('(2 (10 (5 11))) (5 6) (4)')
    #returns [[2, [10, [5, 11]]], [5, 6], [4]]

This first defines an integer as something consisting only of numbers, and tells pyparsing how to convert it from a string of numbers to an integer object. Next, it makes defines an expression as a list of expressions or integers inside parentheses. Finally, in order to parse your example, it looks for many consecutive expressions.

1 Comment

Even simpler is to recognize that nestedExpr internally handles repetition and nesting of the content - just define expr as expr = pp.nestedExpr(content=integer). (Good use of a parse action to convert the numeric strings to integers at parse time, btw. And also a nice summary description of the makeup of the overall parser.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.