Reputation: 607
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
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
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
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