Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am trying to replace blank values in a certain column (column 6 'Author' for example) with "DMD" in CSV using Python. I am fairly new to the program, so a lot of the lingo throws me. I have read through the CSV Python documentation but there doesn't seem to be anything that is specific to my question. Here is what I have so far. It doesn't run. I get the error 'dict' object has no attribute replace. It seems like there should be something similar to replace in the dict. Also, I am not entirely sure my method to search the field is accurate. Any guidance would be appreciated.

import csv
inputFileName = "C:\Author.csv"
outputFileName = os.path.splitext(inputFileName)[0] + "_edited.csv"

field = ['Author']

with open(inputFileName) as infile, open(outputFileName, "w") as outfile:
    r = csv.DictReader(infile)
    w = csv.DictWriter(outfile, field)
    w.writeheader()
    for row in r:
        row.replace(" ","DMD")
        w.writerow(row)
share|improve this question

3 Answers 3

I think you're pretty close. You need to pass the fieldnames to the writer and then you can edit the row directly, because it's simply a dictionary. For example:

with open(inputFileName, "rb") as infile, open(outputFileName, "wb") as outfile:
    r = csv.DictReader(infile)
    w = csv.DictWriter(outfile, r.fieldnames)
    w.writeheader()
    for row in r:
        if not row["Author"].strip():
            row["Author"] = "DMD"
        w.writerow(row)

turns

a,b,c,d,e,Author,g,h
1,2,3,4,5,Smith,6,7
8,9,10,11,12,Jones,13,14
13,14,15,16,17,,18,19

into

a,b,c,d,e,Author,g,h
1,2,3,4,5,Smith,6,7
8,9,10,11,12,Jones,13,14
13,14,15,16,17,DMD,18,19

I like using if not somestring.strip(): because that way it won't matter if there are no spaces, or one, or seventeen and a tab. I also prefer DictReader to the standard reader because this way you don't have to remember which column Author is living in.

[PS: The above assumes Python 2, not 3.]

share|improve this answer
    
Thanks DSM. That worked out wonderfully! –  Devin Murphy Apr 29 '13 at 19:33

Dictionaries don't need the replace method because simple assignment does this for you:

for row in r:
    if row[header-6] == "":
        row[header-6] = "DMD"
    w.writerow(row)

Where header-6 is the name of your sixth column

Also note that your call to DictReader appears to have the wrong fields attribute. That argument should be a list (or other sequence) containing all the headers of your new CSV, in order.

For your purposes, it appears to be simpler to use the vanilla reader:

import csv
inputFileName = "C:\Author.csv"
outputFileName = os.path.splitext(inputFileName)[0] + "_edited.csv"

with open(inputFileName) as infile, open(outputFileName, "w") as outfile:
    r = csv.reader(infile)
    w = csv.writer(outfile)
    w.writerow(next(r))  # Writes the header unchanged
    for row in r:
        if row[5] == "":
            row[5] = "DMD"
        w.writerow(row)
share|improve this answer

(1) to use os.path.splitest, you need to add an import os

(2) Dicts don't have a replace method; dicts aren't strings. If you're trying to alter a string that's the value of a dict entry, you need to reference that dict entry by key, e.g. row['Author']. If row['Author'] is a string (should be in your case), you can do a replace on that. Sounds like you need an intro to Python dictionaries, see for example http://www.sthurlow.com/python/lesson06/ .

(3) A way to do this, that also deals with multiple spaces, no spaces etc. in the field, would look like this:

field = 'Author'
marker = 'DMD'
....

## longhand version
candidate = str(row[field]).strip()
if candidate:
    row[field] = candidate
else:
    row[field] = marker

or

## shorthand version
row[field] = str(row[field]).strip() and str(row[field]) or marker

Cheers

share|improve this answer
1  
I think using and/or here is much less clear than using a ternary, i.e. row[field] = marker if not row[field].strip() else row[field] or something. And the str is unncessary. –  DSM Apr 29 '13 at 16:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.