Reputation: 1380
I have the following code which takes a csv
file and chops out only the columns that match the fields
list.
def mi_columnDeleter(filenameWithPath):
#The fields I want
fields = ["Part Number", "Full MI", "Accepts", "Attempts"]
#Open the file
infile = codecs.open(filenameWithPath, 'rb')
#hook the DictReader
r = csv.DictReader(infile)
#error occurs here because I have it before 'r' below
infile.close()
#open the same file
outfile = open(filenameWithPath, "wb")
w = csv.DictWriter(outfile, fields, extrasaction="ignore")
w.writeheader()
for row in r:
w.writerow(row)
outfile.close()
I get the following I/O error I/O operation on closed file
because I have infile.close()
before I use r
.
My question is there a way to read in the csv data - chop it down to the correct columns - then save it back to the same file?
I know there are workarounds but I'm sure that python should be able to do this.
Upvotes: 1
Views: 1818
Reputation: 180481
If you want to reopen the same file for writing you need to store the rows in a list first, you cannot close the file and then try to iterate over the lines:
r = csv.DictReader(infile)
r = list(r)
..........
A better approach would be writing to a tempfile, using shutil.move to replace the original file after updating:
from shutil import move
from tempfile import NamedTemporaryFile
import csv
import os
def mi_columnDeleter(filenameWithPath):
fields = ["Part Number", "Full MI", "Accepts", "Attempts"]
with codecs.open(filenameWithPath, 'rb') as f, NamedTemporaryFile("w",dir=".", delete=False) as temp:
r = csv.DictReader(f)
w = csv.DictWriter(temp, fields, extrasaction="ignore")
w.writeheader()
w.writerows(r)
move(temp.name,filenameWithPath)
Using as input:
a,b,c
1,2,3
4,5,6
and fields defined as fields = ["a","c"]
would output:
a,c
1,3
4,6
You can also simply call writerows
passing in the reader object with using the for loop in your own code.
Upvotes: 2