1

For example,

string = "['SING', 'Dance'],['Talk', 'Scream'],['Run', 'Walk']"

How can I make a new list with each list above as an element of my new list?

I tried doing

string = string.split (',')

but it splits it by the commas inside my lists also, which is something I don't want.

Shai
  • 102,241
  • 35
  • 217
  • 344

4 Answers4

5

You could use ast.literal_eval:

>>> import ast
>>> strs = "['SING', 'Dance'],['Talk', 'Scream'],['Run', 'Walk']"
>>> ast.literal_eval("[" + strs + "]")
[['SING', 'Dance'], ['Talk', 'Scream'], ['Run', 'Walk']]
Ashwini Chaudhary
  • 232,417
  • 55
  • 437
  • 487
1
>>> eval("['SING', 'Dance'],['Talk', 'Scream'],['Run', 'Walk']")
>>> (['SING', 'Dance'], ['Talk', 'Scream'], ['Run', 'Walk'])
>>>
>>> list(eval("['SING', 'Dance'],['Talk', 'Scream'],['Run', 'Walk']"))
>>> [['SING', 'Dance'], ['Talk', 'Scream'], ['Run', 'Walk']]

Why does eval("'a',2,[12,'bb']") return ('a', 2, [12, 'bb']) while there are no ( in front of and no ) at the end of the evaluated string ?
We must think to how the interpreter acts when it encounters the evaluated expression as the right part of an expression from which it performs an unpacking.
When the interpreter executes the following line (in which there are no parens)

x,y,z = 'a',2,[12,'bb']

what is performed is:
- evaluation of the right part, that's doing eval("'a',2,[12,'bb']") and it creates a tuple
- evaluation of the left part
- unpacking of the right tuple in the left tuple

eyquem
  • 25,715
  • 6
  • 36
  • 44
  • @Haidro I know it's touchy to use **eval()**. But I think it's to everybody to take care of the conditions in which one uses it. That's why it's a good point to give a link to this info. But read also the comments of S.Lott and martineau on the page you gave link of. If it was so much dangerous, why is it still present in Python ? I think we must avoid to have pavlovian reflexes eachtime we see certain subjects as 'eval', 'regex for HTML', etc – eyquem May 25 '13 at 08:55
0

A one-liner that would work for your specific example:

>>> string = "['SING', 'Dance'],['Talk', 'Scream'],['Run', 'Walk']"
>>> [x.split(', ') for x in string[1:-1].replace("'", "").split('],[')]
[['SING', 'Dance'], ['Talk', 'Scream'], ['Run', 'Walk']]

This is fragile, because it depends on the strings working exactly as you have them laid out. It applies the following steps:

  1. string[1:-1] - throw out the [ and ] that bracket the string.
  2. replace("'") - throw out all single quotes because they will not help the split.
  3. split('],[') - split the outermost string on the substring that connects the sublists.
  4. [x.split(', ') for x in ... - FOR EACH GENERATED SUBSTRING, split that substring on its internal pair connector - in this case, `.

This is more proof of concept that this can be done, rather than a really good idea. This is a very fragile solution, because any irregularity in spacing or quoting will break it.


A better solution would be to use a regular expression to find the substrings that match lists, get a list of those, and process those into lists.

regex_string = '(?<=\[)[^\]]+(?=\])'
matcher = re.compile(regex_string)
substring_list = matcher.findall(string)
list_of_lists = [x.split(', ') for x in substring_list]
pcurry
  • 1,314
  • 11
  • 22
0
>>> for i in string.split(","):
...     print i
... 
['SING'
 'Dance']
['Talk'
 'Scream']
['Run'
 'Walk']
Rajeev
  • 42,191
  • 76
  • 179
  • 280