1

I have a CSV file that was written by a CSV Writer. There is a single empty line at the end of the file that I need to remove. I cannot seem to get rid of it, and my search results are inundated with people asking why there is a blank line between each row of data (which is of course solved by adding newline="" to the file open statement.

Is there a way to cleanly do this? This is the code:

with open(r"file.csv", "w", newline="") as f:
    csv_writer = writer(f, delimiter=";")
    for i in range(5):
        csv_writer.writerow([i, uniform(0,500)])

And this is the output (actually making the last line empty will not show up in markdown it seems:

0;479.9182863880229
1;397.35174552864135
2;390.33911360875913
3;243.78955947710557
4;171.04998742391697
<empty line here>

I don't like this solution, which is in the same vein as the responses to this question:

lines = file.readlines()
lines = lines[:-1]

Because it requires me to read the entire file again, and I am expecting that this file may grow to an extremely large size, and this particular block of code may end up getting executed many many times over.

wfgeo
  • 1,491
  • 3
  • 18
  • 35
  • 1
    Possible duplicate of [Python CSV Writer leave a empty line at the end of the file](https://stackoverflow.com/questions/29335614/python-csv-writer-leave-a-empty-line-at-the-end-of-the-file) – Jimmy Smith Oct 31 '18 at 15:14
  • @JimmySmith both of those solutions require reading the entire file again which I am trying to avoid. – wfgeo Oct 31 '18 at 15:16
  • That is slightly different. What happens when you open with "wb" instead of "w", [taken from this answer](https://stackoverflow.com/questions/14693646/writing-to-csv-with-python-adds-blank-lines) – Jimmy Smith Oct 31 '18 at 17:59

1 Answers1

1

I finally found a solution that works and does not necessitate reading the entire file again:

with open(r"file.csv", "w", newline="") as f:
    csv_writer = writer(f, delimiter=";")
    for i in range(5):
        csv_writer.writerow([i, uniform(0, 500)])

f.seek(0, os.SEEK_END)
f.seek(f.tell()-2, os.SEEK_SET)
f.truncate()
wfgeo
  • 1,491
  • 3
  • 18
  • 35
  • 1
    Careful, if you need your code to be platform-independent you will need to work out the length of your line-endings, which may be 1 instead of 2 – Julian Feb 13 '20 at 15:35