3

I have the list of strings:

['[12 9 15]','[98 12 18]','[56 45 45]']   

and I want to convert it to

[[12,9,15],[98,12,18],[56,45,45]]
Matthias
  • 10,297
  • 5
  • 38
  • 43
hen shalom
  • 107
  • 1
  • 1
  • 6

6 Answers6

6

You can use split inside a list comprehension to do this.

As [1 2 3] is not the proper representation of a python list in a string, we can remove the brackets to get '1 2 3' which on splitting becomes ['1', '2', '3']. This can be easily converted to a integer nested list by casting it to an int using the int callable.

>>> l = ['[12 9 15]','[98 12 18]','[56 45 45]']   
>>> [[int(j) for j in i[1:-1].split()] for i in l]
[[12, 9, 15], [98, 12, 18], [56, 45, 45]]

For further reading What does "list comprehension" mean? How does it work and how can I use it?

Community
  • 1
  • 1
Bhargav Rao
  • 41,091
  • 27
  • 112
  • 129
  • @henshalom Yes, Use the `float` buitin. `[[float(j) for j in i[1:-1].split()] for i in l]` – Bhargav Rao Jun 24 '16 at 21:13
  • It works, but when I run it on my list i get [12, enter 15, enter 455 enter ... it skips lines – hen shalom Jun 24 '16 at 21:17
  • @henshalom Does your string input contain newlines? If yes, then [`strip`](https://docs.python.org/2/library/stdtypes.html#str.strip) them out. If you can provide a example input with the newlines, I can certainly help you out. – Bhargav Rao Jun 24 '16 at 21:21
  • the code that i use is this http://pastebin.com/aPWBsy21 and the file is https://www.dropbox.com/s/a1bhvywfrx76xio/Lin%20%281%29.txt?dl=0 – hen shalom Jun 24 '16 at 21:29
  • @henshalom Oops, You are using numpy to read a csv file? You can use a [`csv.reader`](https://docs.python.org/2/library/csv.html#csv.reader) that handles your style of data much better. Is it possible to create a minimal rep of that data? 180 lines is *too* much for a [mcve]. – Bhargav Rao Jun 24 '16 at 21:35
  • Another sad story is that dropbox has converted the tabs to spaces. So a minimal example with tabs would be helpless too! – Bhargav Rao Jun 24 '16 at 21:42
2

Your strings [12 9 15] aren't formatted like python lists (commas are missing). You've got a couple options depending on how robust your parser needs to be:

import ast
out_list = []
for string_list in list_of_strings:
    list_repr = ','.join(string_list.split())
    out_list.append(ast.literal_eval(list_repr))

This will work so long as you don't have any inner strings formatted like:

'[ 12 9, 5] (the leading space will mess it up)

I think that probably the most robust parser that I can think of is to remove the [ and ] and them parse it yourself:

out_list = []
for string_list in list_of_strings:
    str_items = string_list.replace('[', '').replace(']', '')
    out_list.append([int(item) for item in str_items.split()])
mgilson
  • 264,617
  • 51
  • 541
  • 636
  • Why aren't you going by the `replace` way? `string_list.replace(' ',',')`. Apologies, If I am missing something there. – Bhargav Rao Jun 24 '16 at 21:20
  • 1
    @BhargavRao -- If there are more than one space in a row in the `string_list`, that'll fail. We want to replace consecutive runs of spaces with a single comma and `str.replace` doesn't do that well. It's a pretty easy `re.sub` if we wanted to go that route, but I thought I'd save OP from having to learn some regular expressions for this simple task. – mgilson Jun 24 '16 at 21:22
2

As long as the strings are fairly regular, this should work:

>>> x = ['[12 9 15]','[98 12 18]','[56 45 45]']   
>>> x = [[int(i) for i in string.strip('[]').split()] for string in x]
>>> x
[[12, 9, 15], [98, 12, 18], [56, 45, 45]]
juanpa.arrivillaga
  • 65,257
  • 7
  • 88
  • 122
1

Use a regular expression

[map(int, re.findall('\d+', item)) for item in x]

In case it is not always well-formated.


>>> import re
>>> [map(int, re.findall('\d+', item)) for item in x]
[[12, 9, 15], [98, 12, 18], [56, 45, 45]]
Bhargav Rao
  • 41,091
  • 27
  • 112
  • 129
LumiG
  • 432
  • 1
  • 6
  • 13
  • 1
    And `list(map(...))` on python3.x ... but I guess that's irrelevant since it's tagged `python2.7`. – mgilson Jun 24 '16 at 21:24
0

The simpler the solution, the better it is for others to understand.

Well here is my solution:

list_of_strings =  ['[12 9 15]','[98 12 18]','[56 45 45]']  
list_of_lists = [map(int, x[1:-1].split()) for x in list_of_strings]

So I using list-comprehension here. The 'map' function returns a list. The code x[1:-1].split() will split each string on space character(s) and the each string token would then be converted to 'int' which is the function I've passed to the map function.

Need more explanation over my code?

Archit Kapoor
  • 814
  • 16
  • 21
0

Please check if this is helpful.

>>> x = ['[12 9 15]','[98 12 18]','[56 45 45]']
>>> print eval(str([ item.replace(" ",",") for item in x ]).replace("'", ''))
[[12, 9, 15], [98, 12, 18], [56, 45, 45]]
SuperNova
  • 15,051
  • 5
  • 67
  • 45