1

I'm struggling with list comprehensions.

Basically I have a simple string:

string =  "['a','b','c','d']"

Note, that the brackets,commas and quotation marks are part of the string. What I need is a list1 with a,b,c,d as elements (so i need to get rid of the quotation marks, the commas and brackets.)

for entry in string:

list1 = [x.lstrip(" ' ") for x in string.split(',')]
list2 = [x.strip(" ' ") for x in list1]

This does not work at all. list1 gets created without the beginning "'", but when I try to print out list2 the quotations are there again. I did not even start dealing with the brackets. Is there a nice way to get my list?

Mazdak
  • 105,000
  • 18
  • 159
  • 188
Rima
  • 25
  • 2
  • I prefer the usage of `ast.literal_eval`, but based on your effort it would look like this: `data = [value.strip("' ") for value in string[1:-1].split(',')]`. – Matthias May 13 '15 at 12:48

6 Answers6

3

If your string is already built as a list object but with quotation marks as you stated:

string =  "['a','b','c','d']"

You can simply make

exec('list1='+string)

As an alternative, you can remove everything that is not commas, and end up with

string = "a,b,c,d"

For instance

import re
string = re.sub(r"[^\w,]", "", string)

And then you use

>>> list1 = string.split(',')
>>> list1
['a','b','c','d']
rafaelc
  • 57,686
  • 15
  • 58
  • 82
3

As a more pythonic way for such tasks you can use ast.literal_eval :

>>> s=  "['a','b','c','d']"
>>> from ast import literal_eval
>>> list1=literal_eval(s)
>>> list1
['a', 'b', 'c', 'd']

ast.literal_eval(node_or_string)

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

You can also use regular expression that is more flexible and useful in other tasks :

Note that in this case using literal_eval is the pythonic way!

>>> import re
>>> re.findall(r'\w+',s)
['a', 'b', 'c', 'd']
Mazdak
  • 105,000
  • 18
  • 159
  • 188
2

ast.literal_eval is the way to go. It won't execute malicious code in case user modifies string to perform some kind of exploit. Check Using python's eval() vs. ast.literal_eval()? for additional information.

import ast
string =  "['a','b','c','d']"
assert ast.literal_eval(string) == ['a','b','c','d']
Community
  • 1
  • 1
Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
0

Using ast.literal_eval

In [110]: from ast import literal_eval

In [111]: li=literal_eval(string)

In [112]: li
Out[112]: ['a', 'b', 'c', 'd']

In [113]: type(li)
Out[113]: list

or alternatively Using Slicing with list comprehension

In [122]: li1=string[1:-1].split(',')
Out[122]: ["'a'", "'b'", "'c'", "'d'"]
In [127]: [elem.strip("'") for elem in li1]
Out[127]: ['a', 'b', 'c', 'd']

or

In [7]: li2=list(string)

In [8]: [elem for elem in li2 if elem.isalpha()]
Out[8]: ['a', 'b', 'c', 'd']
Brian Lee
  • 158
  • 4
Ajay
  • 5,267
  • 2
  • 23
  • 30
0

You can use replace(). try to this

>>> string =  "['a','b','c','d']"
>>> string.replace("'", "")
'[a,b,c,d]'
>>> print string.replace("", "")
['a','b','c','d']
>>> print string.replace("'", "")
[a,b,c,d]
Haresh Shyara
  • 1,826
  • 10
  • 13
0

Here is you desired solution I don't know the complexity of this but this is simple solution you just need to add one condition in list comprehension.

string =  "['a','b','c','d']"
l = [x for x in string if x not in ['"',"[","]","'",',']]

output would be l= ['a', 'b', 'c', 'd']

Note: This is just for given input, output may vary if input changed.

Abdul Majeed
  • 2,671
  • 22
  • 26