Ben C Wang
Ben C Wang

Reputation: 607

csv.reader() is separating values by individual character

I have the following code trying to iterate over some items:

Here is the input (Single line)

operation,sku,item_name,upc,ean,brand_name

   filename=open("WebstoreItemTemplate.csv").read()
   template=csv.reader(filename,delimiter=',')
   for row in template:
        print row

I'm expecting the output to look the same, something like:

['operation','sku','item_name','upc,ean','brand_name']

instead I'm receiving the following output with each letter being treated as a list. I've verified that the file is in csv format, so I'm unsure what I'm doing wrong.

['o']
['p']
['e']
['r']
['a']
['t']
['i']
['o']
['n']
['', '']
['s']
['k']
['u']
['', '']
['i']
['t']
['e']
['m']
['_']
['n']
['a']
['m']
['e']
['', '']
['u']
['p']
['c']
['', '']
['e']
['a']
['n']
['', '']
['b']
['r']
['a']
['n']
['d']
['_']
['n']
['a']
['m']
['e']

Upvotes: 13

Views: 8393

Answers (3)

LucasY
LucasY

Reputation: 76

In case anyone is like me and didn't read the manual:

I was seeing the same behavior (splitting on every character) but my reason was that I wasn't reading the csv from a file, but from a string. The python csv reader expects a file, or a file-like object. My solution was to use

stringAsFile = io.StringIO(myCSVString)

which allowed me to use csv.reader() as expected.

Hope it helps

Upvotes: 0

Andreas
Andreas

Reputation: 1160

You just need to call splitlines() after calling read. Passing the file object is not always ideal or required.

For example reading from string:

import csv
rawdata = 'name,age\nDan,33\nBob,19\nSheri,42'
myreader = csv.reader(rawdata.splitlines())
for row in myreader:
    print(row[0], row[1])

in my case I just wanted to detect encoding using chardet:

with open("WebstoreItemTemplate.csv") as f:
     raw_data = f.read()
     encoding = chardet.detect(raw_data)['encoding']
     cr = csv.reader(raw_data.decode(encoding).splitlines())
...

Here are some practical examples that I have personally found useful: http://2017.compciv.org/guide/topics/python-standard-library/csv.html

Upvotes: 5

Padraic Cunningham
Padraic Cunningham

Reputation: 180481

Remove the .read and just pass the file object:

with open("WebstoreItemTemplate.csv") as filename:
    template=csv.reader(filename)
    for row in template:
        print row

Which will give you:

['operation', 'sku', 'item_name', 'upc', 'ean', 'brand_name']

From the docs:

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.

Basically this is happening:

In [9]: next(iter("foo"))
Out[9]: 'f'

Upvotes: 13

Related Questions