0

I know there are similar posts to this topic, however they often focus on the list items being letters and so the outcome often means they are wrapped in double quotes.

However, I am dealing with lists of numbers and I have been unable to find a solution that addresses my need for converting a string representation of a list of numerical lists ...

"[1,2,3,4,5,6],[5,1,4,6,3,2],[3,6,4,1,5,2]"

... into an actual list of numerical lists, as I mentioned I am dealing with numerical items for math.

list_string = "[1,2,3,4,5,6],[5,1,4,6,3,2],[3,6,4,1,5,2]"
ini_list = "[" + list_string + "]"

goal = list(ini_list)
print(goal)

#Desired Outcome:    
#goal = [[1,2,3,4,5,6],[5,1,4,6,3,2],[3,6,4,1,5,2]]
S3DEV
  • 8,768
  • 3
  • 31
  • 42
sarahParker
  • 113
  • 4

4 Answers4

0

You can use exec() function, that executes python code.

>>> exec("a = [[1,2,3,4,5,6],[5,1,4,6,3,2],[3,6,4,1,5,2]]")
>>> a
[[1, 2, 3, 4, 5, 6], [5, 1, 4, 6, 3, 2], [3, 6, 4, 1, 5, 2]]
Urh
  • 187
  • 1
  • 1
  • 12
0

A very simple (and safe/robust) approach is to use the ast.literal_evel function.

In this case, the ast.literal_eval function is a safe way to evaluate strings and convert them to their intended type, as there is logic in the function to help remove the risk of evaluating malicious code.

Use:

import ast

list_string = "[1,2,3,4,5,6],[5,1,4,6,3,2],[3,6,4,1,5,2]"
result = ast.literal_eval(f'[{list_string}]')

Output:

 [[1, 2, 3, 4, 5, 6], [5, 1, 4, 6, 3, 2], [3, 6, 4, 1, 5, 2]]    
S3DEV
  • 8,768
  • 3
  • 31
  • 42
0

Here is one faster way to do so using list comprehension and split():

list_string = "[1,2,3,4,5,6],[5,1,4,6,3,2],[3,6,4,1,5,2]"

goal = [[int(num) for num in sublist.split(",")] for sublist in list_string[1:-1].split("],[")]
print(goal)  # [[1, 2, 3, 4, 5, 6], [5, 1, 4, 6, 3, 2], [3, 6, 4, 1, 5, 2]]

  • We separate the string at each ],[, to retrieve the different sublists.
  • Then, we separate each sublist at , and finally convert the separated numbers to integers.

The alternative with for loops would be:

goal = []
for sublist in list_string[1:-1].split("],["):
    new_sublist = []
    for num in sublist.split(","):
        new_sublist.append(int(num))
    goal.append(new_sublist)
print(goal)
Cubix48
  • 2,607
  • 2
  • 5
  • 17
0

If you take list(string) you will just split string into chars. For example list('[1, 2]') = ['[', '1', ',', ' ', '2', ']'].

But what you have is a string containing a python literal (a piece of code that describes a value). And you need to turn it into actual value. For that there is eval function. So just do goal = eval(ini_list). Hope I helped you.

  • Please [read this question](https://stackoverflow.com/q/1832940/6340496) and understand it *thoroughly* before recommending the `eval` function. – S3DEV Mar 27 '22 at 18:41
  • @S3DEV , if you properly know what the string contains, then there is nothing bad in using eval. At least it is better than `split`. – Усердный бобёр Mar 27 '22 at 18:46
  • @Усердныйбобёр I'm sure you'll find interesting the fact that using `split()` is actually way faster than using `eval()` (With `timeit`, 20.476404585002456 secs for `eval()` and 2.5082522810043884 for `split()`). – Cubix48 Mar 27 '22 at 18:54
  • @Cubix48 What times do you get for `ast.literal_eval` and `json.loads`? – Kelly Bundy Mar 27 '22 at 18:59
  • @Cubix48 , I think that speed is not the main thing to worry about. If you want high speed - probably you are right. Even better thing to do to get high speed is to use `numba` package. But didn't you think about bugs? What if there is one more or one less space for example? It will break! – Усердный бобёр Mar 27 '22 at 19:01
  • @KellyBundy There is not a big difference with ``json.loads()`` (2.183866539002338 secs), but ``ast`` is much slower (26.570625692998874 secs). @Усердныйбобёр If we are unsure of the formatting of the initial list, I think using ``replace(" ", "")`` eliminates all problems :) – Cubix48 Mar 27 '22 at 19:10
  • @Cubix48 - How in the world are you getting 20 seconds (eval) and 26 seconds (literal_eval)? Mine runs in 66us. What am I missing here ...? – S3DEV Mar 27 '22 at 19:37
  • @S3DEV I used ``timeit``, so the comparison is based on 1000000 repetitions. – Cubix48 Mar 27 '22 at 19:51