42
votes

I'm trying to use Python 3.2 on a Windows computer to write a simple CSV file, however I'm having no luck. From the csv module documentation for Python 3.2:

>>> import csv
>>> spamWriter = csv.writer(open('eggs.csv', 'w'), delimiter=' ',
...                         quotechar='|', quoting=csv.QUOTE_MINIMAL)
>>> spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
>>> spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])

produces a file with each line terminated by the byte sequence \r\r\n, so it looks like each line has an extra empty line when you open it with, e.g., MS Excel. This is not a "CSV file".

Note, if I try the same example for Python 2.7 in Python 3.2 (where the big difference is 'w' vs 'wb' for the file mode), I get an error when I try spamWriter.writerow:

Traceback (most recent call last): File "", line 1, in TypeError: 'str' does not support the buffer interface

How do I write a simple CSV file from Python 3.2 on a Windows computer?

6
The problem seems to be Windows-specific. Works fine on Linux.phihag

6 Answers

66
votes

Documentation says that you should use open('eggs.csv', 'w', newline='')

http://docs.python.org/py3k/library/csv.html#id2

19
votes

This will work on both Python 2 and Python 3:

if sys.version_info >= (3,0,0):
    f = open(filename, 'w', newline='')
else:
    f = open(filename, 'wb')
7
votes

As documented in a footnote:

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

If csvfile is a file object, it should be opened with newline=''.

If newline='' is not specified, newlines embedded inside quoted fields will not be interpreted correctly, and on platforms that use \r\n linendings on write an extra \r will be added. It should always be safe to specify newline='', since the csv module does its own (universal) newline handling.

The following variant works on Linux and Windows:

spamWriter = csv.writer(open('eggs.csv', 'wb'), delimiter=' ', quotechar='|',
                        quoting=csv.QUOTE_MINIMAL, newline='')
spamWriter.writerow(['Spam'] * 5 + ['Baked Beans'])
spamWriter.writerow(['Spam', 'Lovely Spam', 'Wonderful Spam'])
2
votes

To directly answer your question, you should be able to use the lineterminator formatting parameter:

...so modifying this line should work (untested):

>>> spamWriter = csv.writer(open('eggs.csv', 'w'), delimiter=' ',
...                         quotechar='|', quoting=csv.QUOTE_MINIMAL, lineterminator='\n')

As for why the example doesn't work out-of-the box, kind of looks like a bug to me.

1
votes

I resolved this error as I was moving one of my codes from Python2.6.6 to python3.4.3

Python2.6.6(I'm trying to do some obfuscation on my csvfile)

with open( os.path.join(path, name) , 'r') as mycsvfile:
writer = csv.writer(open(newFilename, 'w'))

Above worked well with python2.6.6 but did not work on python3.4.3 as I was getting some utf-8 unicode errors when i tried to run the python3 file, so I made the below changes Python3.4.4

import codecs
with codecs.open(os.path.join(path, name) , 'r', encoding='ISO-8859-1') as mycsvfile:
writer = csv.writer(open(newFilename, 'w'))

That's it, my code works fine now, basically python3 is not considering some of the unicode and we need to use the codecs import to make it working, hope it helps..

1
votes

[For Python 2.x] This implementation of spamWriter is working for me...

with open('assignmentresults.csv', 'wb') as csvfile:
  spamwriter = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
  spamwriter.writerow(["Hullo", "World"])