Is there a way to convert a list containing arithmetic operations which is written as a string into an actual list?

Viewed 109

I would like to convert a String like:

s = "[2-1,2,3]"

into a list, like:

a = [1,2,3]

I tried it with json:

s = "[2-1,2,3]"
a = json.loads(s)

but it can't handle 2-1. Is there an easy method to convert strings into any kind of datatype?

2 Answers

Yes. And as much as it pains me to say it, eval is your friend here, as even ast.literal_eval cannot parse this.

  • Please read this first: eval: bad practice?, and please ensure you have complete control over the expressions being evaluated.
  • To help lessen the expressions being evaluated, I've wrapped this solution in regex, to extract only numbers and (in this case) the minus sign.
  • Obviously, this might need tweaking for your specific use case, this this should give you a boiler-plate (or at least an idea) from which to start.

Example code:

import re

s = "[2-1,2,3]"
rexp = re.compile('[\d-]+')

out = []
for exp in rexp.findall(s):
    out.append(eval(exp))

Or, if you prefer a one-liner:

out = [eval(exp) for exp in rexp.findall(s)]

Output:

[1, 2, 3]

This is a common problem to tackle while writing compilers. Usually this comes under lexing. A parser would usually have a list of tokens, watch for the tokens and then pass it to a parser and then the compiler.

Your problem cannot be completely solved with a lexer though since you also require the 2-1 to evaluate to 1. In this case, I would suggest using eval like @Daniel Hao suggested since it is a simple and clean way of achieving your goal. Remember about the caveats(both security and otherwise) while using it though. (especially, in production)

If you are interested in the parsing though, check this out:

  1. https://craftinginterpreters.com/contents.html
  2. https://tomassetti.me/parsing-in-python/
Related