85

I have a string that looks identical to a list, let's say:

fruits = "['apple', 'orange', 'banana']"

What would be the way to convert that to a list object?

Markum
  • 3,669
  • 8
  • 23
  • 30

3 Answers3

124
>>> fruits = "['apple', 'orange', 'banana']"
>>> import ast
>>> fruits = ast.literal_eval(fruits)
>>> fruits
['apple', 'orange', 'banana']
>>> fruits[1]
'orange'

As pointed out in the comments ast.literal_eval is safe. From the docs:

Safely evaluate an expression node or a string containing a Python expression. The string or node provided may only consist of the following Python literal structures: strings, numbers, tuples, lists, dicts, booleans, and None.

This can be used for safely evaluating strings containing Python expressions from untrusted sources without the need to parse the values oneself.

fraxel
  • 31,038
  • 11
  • 87
  • 96
  • 2
    *Note*: this doesn't work if you call a function inside of the array (or any type except strings, numbers, tuples, lists, dicts, booleans, and None). For these cases, you can use `eval`. – Arka May 27 '12 at 17:31
  • 4
    Note on note: `ast.literal_eval` is successful only for literals and nothing else. It *does protect* your program from code injection, for instance `"['apple', 'orange', 'banana'];import os;os.remove('a_file')"` will fail with `literal_eval` – Boud May 27 '12 at 17:39
  • I also have same issue but the my string list is like this `fruits = "['apple', 'orange', 'banan'a']"` how would you handle that comma between `banana` and `a`. – Muhammad Taqi Sep 10 '15 at 06:41
  • Saved me from getting into strings operations. – TheExorcist Dec 26 '16 at 11:17
30

A simple call to eval() will do:

fruits = eval("['apple', 'orange', 'banana']")
fruits
> ['apple', 'orange', 'banana']

Or as explained in this article, the same can be accomplished a bit more safely (meaning: without risking unintended side-effects or malicious code injections) like this:

fruits = eval("['apple', 'orange', 'banana']", {'__builtins__':None}, {})

This solution has the advantage of not depending on additional modules.

Óscar López
  • 215,818
  • 33
  • 288
  • 367
  • 6
    This is accomplished a little more safely using `eval(frtstring,{__builtins__:None},{})` – mgilson May 27 '12 at 17:34
  • @mgilson thanks for the tip, I updated my answer – Óscar López May 27 '12 at 17:37
  • 10
    -1 There is no reason to use `eval()` here. `ast.literal_eval()` will do the job in a much better, safer way. – Gareth Latty May 27 '12 at 17:48
  • Oops, I think it should be `{'__builtins__':None}`. Sorry about that. – mgilson May 27 '12 at 20:13
  • -1 No need for this hack when you can use `ast`. – jamylak May 28 '12 at 02:09
  • 5
    While `ast.literal_eval` is better for this, `eval` works (and it is a useful once in a while so it is worth knowing about). I don't see any reason to downvote it since it does do what the question asked (+1 from me). – mgilson May 28 '12 at 13:47
  • 3
    @mgilson: there are severe security implications to using `eval()`, that even `{'__builtins__': None}` is not going to save you from. – Martijn Pieters Nov 05 '14 at 08:40
  • @MartijnPieters That's why I said "a _little_ more safely", but I suppose any discussion in this vein is probably remiss without a link to [Ned's article](http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html) on exactly why using `{'__builtins__': None}` should be a no-go. – mgilson Nov 05 '14 at 15:29
2

I think this is what ast.literal_eval is for.

( http://docs.python.org/library/ast.html#ast.literal_eval )

mgilson
  • 264,617
  • 51
  • 541
  • 636