Padaca
Padaca

Reputation: 347

Is there a way to use Python's csv.reader() on csv files without quoted fields?

I'm trying to read from a csv file that contains responses to questions and the scores belonging to those responses. It looks like

id,answer,cat1,cat2,cat3,cat4
10000001,"This is my response to the question. I think it's a good response!",100,100,50,50

I'd like to simply read these values into a list.

However, in the app this is for, a file is uploaded to a webpage, accessed as a workzeug.FileStorage object, then passed to the backend as a bytes object. In my code, I attempt to convert it to a string, then use csv.reader() to convert it to a list.

Here's the relevant code:

def foo(_file):
    file = _file.decode()
    print(file)
    file = list(csv.reader(file))
    print(file)

Here's the problem: csv.reader() seems to be separating on things that aren't commas. In fact, its splitting everything that isn't enclosed in quotes into individual characters, including commas. Here's what the second print() outputs:

[['i'], ['d'], ['', ''], ['a'], ['', ''], ['c'], ['a'], ['t'], ['1'], ['', ''], ['c'], ['a'], ['t'], ['2'], ['', ''], ['c'], ['a'], ['t'], ['3'], ['', ''], ['c'], ['a'], ['t'], ['4'], [], ['1'], ['0'], ['0'], ['0'], ['0'], ['0'], ['0'], ['1'], ['', ''], ["This is my response to the question. I think it's a good response!"], ['', ''], ['1'], ['0'], ['0'], ['', ''], ['1'], ['0'], ['0'], ['', ''], ['5'], ['0'], ['', ''], ['5'], ['0']]

It doesn't seem like csv.reader() usually required quotes by default... so what's going on here? Thanks!

I'm using Python 3.7.9

Upvotes: 1

Views: 44

Answers (2)

H L
H L

Reputation: 56

csv.reader expects a file object not a filename, e.g.

# file is the csv filename, e.g. /tmp/ex.csv
for t in csv.reader(open(file)):
  print(t)

# Outputs:
['id', 'answer', 'cat1', 'cat2', 'cat3', 'cat4']
['10000001', "This is my response to the question. I think it's a good response!", '100', '100', '50', '50']

Upvotes: 1

Barmar
Barmar

Reputation: 782407

csv.reader() requires its argument to be an iterator that returns lines. You're giving it the entire file contents as a single string, so it treats each character as a line.

You need to split it at newline characters to get a sequence of lines.

def foo(_file):
    file = _file.decode()
    print(file)
    file = list(csv.reader(file.split('\n')))
    print(file)

Upvotes: 0

Related Questions