11

I want to append to a new row in my CSV file when i write to it. Current CSV file look like this:

a,b,c
1,1,1

my code to append to CSV file:

with open('mycsvfile.csv','a') as f:
    writer=csv.writer(f)
    writer.writerow(['0','0','0'])

new mycsvfile:

a,b,c
1,1,1,0,0,0

What i want:

a,b,c
1,1,1
0,0,0
jxn
  • 7,685
  • 28
  • 90
  • 172
  • Just a hint. If you use the original code from jxn to create a new csv file and append to it, it works without problems. JNX problem was, that their file was missing a new-line character at the end when they opened it to append `['0','0','0']`. – Framester Apr 24 '18 at 15:35

3 Answers3

10

With some tinkering I realized you can add the following line to make sure you begin writing on a new line in a csv. Though it seems kind of hackish. Documentation mentions a lot about a kwarg newline='', but it wasn't recognized as valid.

writer.writerow([])

I also open with 'ab' parameter.

import csv
with open('mycsvfile.csv','ab') as f:
    writer=csv.writer(f)
    writer.writerow([])
    writer.writerow(['0','0','0'])
Chasevanb
  • 418
  • 3
  • 10
  • If you running the code two times and trying to write two lines, there will be something wrong. Additional blank lines will be created. – Yunhe Mar 12 '16 at 01:13
  • @Yunhe Why? If you are adding multiple new rows with a loop, no need to include the blank list in that loop. And if you were to add another writerow manually it would still work correctly not producing blank lines. – Chasevanb Mar 12 '16 at 01:19
  • I mean if just run the code twice or more, without modifying anything, blank lines will be created. – Yunhe Mar 12 '16 at 01:23
  • Oh, yes because the writerow method adds a line, so a new line is not needed in the 2nd+ run. No need for the blank writerow list on 2nd+ run. Seems like the method intends for CSVs to end with a new line. – Chasevanb Mar 12 '16 at 01:31
9

The problem is your original file didn't have a final newline written to it. this reproduces the problem:

#!python3
import csv

#initial content
with open('mycsvfile.csv','w') as f:
    f.write('a,b,c\n1,1,1') # NO TRAILING NEWLINE

with open('mycsvfile.csv','a',newline='') as f:
    writer=csv.writer(f)
    writer.writerow([0,0,0])
    writer.writerow([0,0,0])
    writer.writerow([0,0,0])

with open('mycsvfile.csv') as f:
    print(f.read())

Output:

a,b,c
1,1,10,0,0
0,0,0
0,0,0

Just make sure the original file was generated properly:

#!python3
import csv

#initial content
with open('mycsvfile.csv','w') as f:
    f.write('a,b,c\n1,1,1\n') # TRAILING NEWLINE

with open('mycsvfile.csv','a',newline='') as f:
    writer=csv.writer(f)
    writer.writerow([0,0,0])
    writer.writerow([0,0,0])
    writer.writerow([0,0,0])

with open('mycsvfile.csv') as f:
    print(f.read())

Output:

a,b,c
1,1,1
0,0,0
0,0,0
0,0,0

You can do some hack to seek to the end of the file and decide to write the extra newline, but better to fix the existing file generation so it always writes newlines. The easiest way to do that is use the csv module from the start, since it will always add a newline with writerow.

Mark Tolonen
  • 166,664
  • 26
  • 169
  • 251
1

seek(0,2) means go to the end position of your file.

writer = open('mycsvfile.csv','a')
writer.seek(0,2)
writer.writelines("\r")
writer.writelines( (',').join(['0','0','0']))
Yunhe
  • 665
  • 5
  • 10