1

I have a string like this:

s = '1,2,"hello, there"'

And I want to turn it into a list:

[1,2,"hello, there"]

Normally I'd use split:

my_list = s.split(",") 

However, that doesn't work if there's a comma in a string.

So, I've read that I need to use cvs, but I don't really see how. I've tried:

from csv import reader
s = '1,2,"hello, there"'
ll = reader(s)
print ll 
for row in ll:
    print row

Which writes:

<_csv.reader object at 0x020EBC70>

['1']
['', '']
['2']
['', '']
['hello, there']

I've also tried with

ll = reader(s, delimiter=',')
3
  • Have you tried a regular expression? Commented Apr 17, 2015 at 21:48
  • where did you get that you need to use a csv to split string? Commented Apr 17, 2015 at 21:55
  • @user984003, please accept one or many of the answers that solve your problem. Commented Apr 18, 2015 at 22:54

5 Answers 5

2

It is that way because you provide the csv reader input as a string. If you do not want to use a file or a StringIO object just wrap your string in a list as shown below.

>>> import csv
>>> s = ['1,2,"hello, there"']
>>> ll = csv.reader(s, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
>>> list(ll)
[['1', '2', 'hello, there']]
Sign up to request clarification or add additional context in comments.

1 Comment

You mention StringIO and file but actually use a list in your example. You can use use any iterable there: list or tuple will work just as fine.
1

It sounds like you probably want to use the csv module. To use the reader on a string, you want a StringIO object.

As an example:

>> import csv, StringIO
>> print list(csv.reader(StringIO.StringIO(s)))
[['1', '2', 'hello, there']]

To clarify, csv.reader expects a buffer object, not a string. So StringIO does the trick. However, if you're reading this csv from a file object, (a typical use case) you can just as easily give the file object to the reader and it'll work the same way.

2 Comments

That seems to work, thanks! Anyone want to tell me why it was downvoted? It does turn the int into strings, but I'm ok with that.
You can use use any iterable, actually: list or tuple will work just as fine.
1

It's usually easier to re-use than to invent a bicycle... You just to use csv library properly. If you can't for some reason, you can always check the source code out and learn how's the parsing done there.

Example for parsing a single string into a list. Notice that the string in wrapped in list.

>>> import csv
>>> s = '1,2,"hello, there"'
>>> list(csv.reader([s]))[0]
['1', '2', 'hello, there']

1 Comment

Thanks for pointing it out. Apparently I wasn't the first with this answer. It's a little weird for me to use SO mobile app.
0

You can split first by the string delimiters, then by the commas for every even index (The ones not in the string)

import itertools

new_data = s.split('"')
for i in range(len(new_data)):
    if i % 2 == 1: # Skip odd indices, making them arrays
       new_data[i] = [new_data[i]]
    else:
        new_data[i] = new_data[i].split(",")
data = itertools.chain(*new_data)

Which goes something like:

'1,2,"hello, there"'
['1,2,', 'hello, there']
[['1', '2'], ['hello, there']]
['1', '2', 'hello, there']

But it's probably better to use the csv library if that's what you're working with.

Comments

0

You could also use ast.literal_eval if you want to preserve the integers:

>>> from ast import literal_eval
>>> literal_eval('[{}]'.format('1,2,"hello, there"'))
[1, 2, 'hello, there']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.