16

I'm having trouble opening a file (amount2.csv) making a change, saving it and closing the file.

How does one open a file edit, save and close it?

import csv

changes = {
    '1 dozen' : '12'
    }
with open('amount2.csv', 'r') as f:
reader = csv.reader(f)
print f
f.close()

my error: open file 'amount2.csv', mode 'r' at 0x1004656f0 (<> removed)

DSM
  • 342,061
  • 65
  • 592
  • 494
Sean
  • 165
  • 1
  • 1
  • 6
  • 2
    This may not be cause of error but please see that you open with b flag i.e. 'rb' instead of r. The docs for csv.reader say "If csvfile is a file object, it must be opened with the ‘b’ flag on platforms where that makes a difference." It is widely known that it does make a difference on Windows. – Sudip Kafle Jan 23 '13 at 02:30

2 Answers2

23

The

<open file 'amount2.csv', mode 'r' at 0x1004656f0>

you are seeing isn't an error, but the result of your 'print f'. To instead see the contents of your file, you would do

with open('test.csv', 'rb') as f:
    reader = csv.reader(f)
    for row in reader:
        # row is a list of strings
        # use string.join to put them together
        print ', '.join(row)

To append rows to your file, instead do

changes = [    
    ['1 dozen','12'],                                                            
    ['1 banana','13'],                                                           
    ['1 dollar','elephant','heffalump'],                                         
    ]                                                                            

with open('test.csv', 'ab') as f:                                    
    writer = csv.writer(f)                                                       
    writer.writerows(changes)

More info at Python CSV Docs

EDIT:

I misunderstood at first, you want to change all entries of '1 dozen' to '12' in your csv file. I will say first, this is easier to do without using the csv module, but here is a solution using it.

import csv

new_rows = [] # a holder for our modified rows when we make them
changes = {   # a dictionary of changes to make, find 'key' substitue with 'value'
    '1 dozen' : '12', # I assume both 'key' and 'value' are strings
    }

with open('test.csv', 'rb') as f:
    reader = csv.reader(f) # pass the file to our csv reader
    for row in reader:     # iterate over the rows in the file
        new_row = row      # at first, just copy the row
        for key, value in changes.items(): # iterate over 'changes' dictionary
            new_row = [ x.replace(key, value) for x in new_row ] # make the substitutions
        new_rows.append(new_row) # add the modified rows

with open('test.csv', 'wb') as f:
    # Overwrite the old file with the modified rows
    writer = csv.writer(f)
    writer.writerows(new_rows)

If you're new to programming and python the most trobulesome line is probably

new_row = [ x.replace(key, value) for x in new_row ]

but this is just a list comprehension that is effectively equivalent to

temp = []
for x in new_row:
    temp.append( x.replace(key, value) )
new_row = temp
kalhartt
  • 3,999
  • 20
  • 25
  • Thanks! I've been reading the documentation, but am new to programming and have a bit of trouble understanding the explanations. I ran into the warning: _csv.Error: new-line character seen in unquoted field - do you need to open the file in universal-newline mode? I was able to fix it with "with open('amount2.csv', 'rU') as f:" – Sean Jan 23 '13 at 03:12
  • [import csv with open('amount2.csv', 'rU') as f: reader = csv.reader(f) for row in reader: # row is a list of strings # use string.join to put them together print ', '.join(row) changes = [ ['1 dozen','12'], ] with open('amount2.csv', 'wb') as f: writer = csv.writer(f) writer.writerows(changes) f.close()]'code' – Sean Jan 23 '13 at 03:15
  • I end up erasing/replacing all the contents of the csv file with '1 dozen','12'. I'd like to only replace each '1 dozen' each time with '12'. – Sean Jan 23 '13 at 03:27
  • Ah, I misunderstood what you wanted to do. I'm sorry. I'll update my answer in a moment. – kalhartt Jan 23 '13 at 03:34
  • as for the 'rU' vs 'rb' vs ..., csv files really should be binary so use 'rb'. However, its not uncommon to have csv files from someone who copied it into notepad on windows and later it was joined with some other file so you have funky line endings. How you deal with that depends on your file and your preference. – kalhartt Jan 23 '13 at 03:57
0

You're trying to print the file object itself, which won't do much useful. Have you looked at the documentation for the CSV module? The very first code example shows you how to use csv.reader.

Chuck Adams
  • 777
  • 6
  • 18