pythoncsvparsingtabulate

csv package parses each char as a row


According to this answer it seems I can parse each row of a CSV file with csv.reader(data, delimiter=",", quotechar='"'), so I made the following MWE (Minimal Working Example):

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import csv

data = """\
1,"A towel,",1.0
42," it says, ",2.0
1337,is about the most ,-1
0,massively useful thing ,123
-2,an interstellar hitchhiker can have.,3"""

csvReader = csv.reader(data, delimiter=",", quotechar='"')
for row in csvReader:
        print(row)

But, instead of getting each line (or at least each row in a specific cell, this code catch every single char in cell). This is the output:

['1']
['', '']
['A towel,']
['', '']
['1']
['.']
['0']
[]
['4']
['2']
['', '']
[' it says, ']
['', '']
['2']
['.']
['0']
[]
['1']
['3']
['3']
['7']
['', '']
['i']
['s']
[' ']
['a']
['b']
['o']
['u']
['t']
[' ']
['t']
['h']
['e']
[' ']
['m']
['o']
['s']
['t']
[' ']
['', '']
['-']
['1']
[]
['0']
['', '']
['m']
['a']
['s']
['s']
['i']
['v']
['e']
['l']
['y']
[' ']
['u']
['s']
['e']
['f']
['u']
['l']
[' ']
['t']
['h']
['i']
['n']
['g']
[' ']
['', '']
['1']
['2']
['3']
[]
['-']
['2']
['', '']
['a']
['n']
[' ']
['i']
['n']
['t']
['e']
['r']
['s']
['t']
['e']
['l']
['l']
['a']
['r']
[' ']
['h']
['i']
['t']
['c']
['h']
['h']
['i']
['k']
['e']
['r']
[' ']
['c']
['a']
['n']
[' ']
['h']
['a']
['v']
['e']
['.']
['', '']
['3']

As you see, the output parsing is not as the expected one.

I was wanting something like:

[[1],["A towel],["],[1.0]],
[[42],[" it says],[ "],[2.0]],
[[1337],[is about the most ],[-1]],
[[0],[massively useful thing ],[123]],
[[-2],[an interstellar hitchhiker can have.],[3]]

So, how can I correctly parse a CSV variable?

Edit

So, it seems to not working exactly when it’s a given char variable or a opened file. The error come from here.


Solution

  • From csv:

    csv.reader(csvfile, dialect='excel', **fmtparams)

    Return a reader object which will iterate over lines in the given csvfile. csvfile can be any object which supports the iterator protocol and returns a string each time its next() method is called — file objects and list objects are both suitable.

    from io import StringIO
    
    data = '''\
    1,"A towel,",1.0
    42," it says, ",2.0
    1337,is about the most ,-1
    0,massively useful thing ,123
    -2,an interstellar hitchhiker can have.,3
    '''
    
    with StringIO(data) as f:
        csvReader = csv.reader(f)
        for row in csvReader:
            print(row)
    
    ['1', 'A towel,', '1.0']
    ['42', ' it says, ', '2.0']
    ['1337', 'is about the most ', '-1']
    ['0', 'massively useful thing ', '123']
    ['-2', 'an interstellar hitchhiker can have.', '3']
    

    This turns the string into a file-like object that csv.reader can iterate over rows. What you where seeing was csv.reader iterating over the characters in the string.