3

I have a string, which is a list of numpy arrays. The string looks like

k = '[array([  0, 269, 175, 377]), array([  0,  56, 149, 163])]'

When I do

ast.literal_eval(k)

I get an error saying malformed node or string.

What is the problem here? Is there any better way to convert it back to a list?

Thanks for help!!

wim
  • 338,267
  • 99
  • 616
  • 750
Nikhil Mishra
  • 1,182
  • 2
  • 18
  • 34

3 Answers3

4

From the ast.literal_eval doc:

The string or node provided may only consist of the following Python literal structures: strings, bytes, numbers, tuples, lists, dicts, sets, booleans, and None.

It is not possible to use literal eval here. Find where these strings are generated in the first place, and implement a proper serialization there - for example using numpy.save.

wim
  • 338,267
  • 99
  • 616
  • 750
2

I am not sure if this is a good approach.

from numpy import array
import ast
import re
k = '[array([  0, 269, 175, 377]), array([  0,  56, 149, 163])]'
val = re.findall(r"\((.*?)\)", k)
val = list(map(ast.literal_eval, val))
val = list(map(array, val))
print(val)

Output:

[array([  0, 269, 175, 377]), array([  0,  56, 149, 163])]
  • Using Regex to extract content between ()
  • Apply ast.literal_eval
  • Apply np.array
Rakesh
  • 81,458
  • 17
  • 76
  • 113
  • 1
    Clever. Works as long as the shape of the OP's data never changes -- I wouldn't go with this as a long-term approach, but could see it as a temporary/interim workaround until whatever is generating the strings in question gets fixed. – Charles Duffy May 29 '18 at 17:32
  • @CharlesDuffy. I agree, it is not a proper solution. Best is to fix at the source of OP's input. – Rakesh May 29 '18 at 17:33
0
import numpy as np

array = np.array
k = '[array([  0, 269, 175, 377]), array([  0,  56, 149, 163])]'
k = eval(k)
print(f"k = {k}, type of k = {type(k)}")
print(type(k[0]))

Output:

k = [array([  0, 269, 175, 377]), array([ 0, 56])], type of k = <class 'list'>

<class 'numpy.ndarray'>
Darsh Shukla
  • 289
  • 4
  • 5
  • The whole point of `literal_eval()` is to avoid using `eval()`, since the latter is dangerous in production code. – SigmaX Jul 16 '21 at 13:35