Brian Powell Brian Powell - 4 months ago 10
Python Question

python handling DictReader missing keys

This script is working fine, until I hit a cell that is empty:

import csv,time,string,os,requests
dw = "\\\\network\\folder\\btc.csv"

inv_fields = ["id", "rsl", "number", "GP%"]

with open(dw) as infile, open("c:\\upload\\log.csv", "wb") as outfile:
r = csv.DictReader(infile)
w = csv.DictWriter(outfile, inv_fields, extrasaction="ignore")
r = (dict((k, v.strip()) for k, v in row.items() if v) for row in r)

wtr = csv.writer( outfile )
wtr.writerow(["id", "resale", "number", "percentage"])
for i, row in enumerate(r, start=1):
row['id'] = i
row['GP%'] = row['GP%'].replace("%","")
w.writerow(row)

print "file successfully saved"


The script is failing on this line:

row['GP%'] = row['GP%'].replace("%","")


and by adding
print i
to the loop I can see it is failing on the line of the .csv file where this input value is blank. How do I take cells with no value into this equation?

The python error:

Traceback (most recent call last):
File "backlog.py", line 80, in <module>
row['GP%'] = row['GP%'].replace("%","")
KeyError: 'GP%'

Answer

You can check if key 'GP%' is the in the row dictionary before attempting to update its value. If it isn't you could assign a default value so the entry related to that id is blank in the output file:

for i, row in enumerate(r, start=1):
    row['id'] = i
    if 'GP%' in row:
         row['GP%'] = row['GP%'].replace('%','')
    else:
         row['GP%'] = ''
    w.writerow(row)

Or use the get method of row to set the default value:

for i, row in enumerate(r, start=1):
    row['id'] = i
    row['GP%'] = row.get('GP%', '').replace('%','')
    w.writerow(row)