1

Say someone gives me a string like:

"[[A,B],[C,D]]"

and I want to extract the list it describes:

[[A,B],[C,D]]

How do I do this?

P.S.

A, B, C, D are just placeholders, they could be numeric values or strings.

user
  • 1,673
  • 3
  • 17
  • 33

2 Answers2

5

To prevent an ValueError: malformed string from being raised when passing the input directly to ast.literal_eval, "s need to be added around the characters in the string:

import ast, re
s = "[[A,B],[C,D]]"
new_s = ast.literal_eval(re.sub('\w+', '{}', s).format(*['"{}"'.format(i) for i in re.findall('\w+', s)]))

Output:

[['A', 'B'], ['C', 'D']]
Ajax1234
  • 58,711
  • 7
  • 46
  • 83
  • That's neat! Never seen that before. – Onilol May 14 '18 at 22:14
  • Actually ast is enough, see my P.S., A,B,C and D are placeholders. Did not know about ast, need to learn, do you have a good link to its use? – user May 14 '18 at 22:19
  • @user See [here](https://stackoverflow.com/questions/15197673/using-pythons-eval-vs-ast-literal-eval) for information specifically regarding `ast.literal_eval` or [here](https://docs.python.org/3/library/ast.html) for more about syntax parsing in Python. – Ajax1234 May 14 '18 at 22:22
2

Based on A, B, C, and D being numbers (int, or float) or strings (str), you can simply use:

l = eval("[[A,B],[C,D]]")

For example:

In [1]: l = eval("[[1,2],[3,4]]")

In [2]: l
Out[2]: [[1, 2], [3, 4]]


In [3]: l = eval("[['Hello', 10],['bye', 100]]")

In [4]: l
Out[4]: [['Hello', 10], ['bye', 100]]

In [5]: l = eval("[[3.14, 1],['bye', 2.72]]")

In [6]: l
Out[6]: [[3.14, 1], ['bye', 2.72]]
lmiguelvargasf
  • 40,464
  • 32
  • 169
  • 172
  • Would you mind commenting on the difference between eval and ast.literal_eval? – user May 14 '18 at 22:42
  • @user, I found this [question](https://stackoverflow.com/questions/15197673/using-pythons-eval-vs-ast-literal-eval) with several answers explaining the difference between `eval` and `ast.literal_eval()`, is it enough for you? – lmiguelvargasf May 14 '18 at 22:45