2

Given the data ['a', '', None, 5] I would like to write a CSV file as:

"a","",,5

If I use QUOTE_NONNUMERIC, as in:

import csv
with open('eggs.csv', 'w') as csvfile:
    spamwriter = csv.writer(csvfile, quoting=csv.QUOTE_NONNUMERIC)
    spamwriter.writerow(['a', None, 5])

I get

"a","","",5

but if I remove the quoting=csv.QUOTE_NONNUMERIC, I get the unquoted empty string from Nona, but I also lose the quotes around the a and the empty string.

a,,,5

Context: I want to write files that can be read using R readr r: read_csv('eggs.csv', na=c(""), quoted_na=FALSE) that can distinguish between the empty string and missing data.

Michal Charemza
  • 25,940
  • 14
  • 98
  • 165
  • 1
    It seems like it is not possible with `csv` module per answer from [here](https://stackoverflow.com/questions/11379300/csv-reader-behavior-with-none-and-empty-string), which is coming from the [documentation](http://docs.python.org/library/csv.html#csv.writer). – ywbaek Jun 06 '20 at 15:45

1 Answers1

3

Using a variation of the answer (and comment) at https://stackoverflow.com/a/11380084/1319998, you can replace None in the data with an instance of:

class EmptyString(int):
    def __str__(self):
        return ''

then this will be output by Python's csv.writer, using quoting=csv.QUOTE_NONNUMERIC as an unquoted empty string. A fuller example:

import csv

class EmptyString(int):
    def __str__(self):
        return ''
EmptyString = EmptyString()

def replace_none_with_emptystring(row):
  return [
    val if val is not None else EmptyString
    for val in row
  ]

with open('eggs.csv', 'w') as csvfile:
    spamwriter = csv.writer(csvfile, quoting=csv.QUOTE_NONNUMERIC)
    spamwriter.writerow(replace_none_with_emptystring(['a', '', None, 5]))

saves

"a","",,5
Michal Charemza
  • 25,940
  • 14
  • 98
  • 165