0

I'm following some feedback from another thread, but have gotten stuck. I'm looking to search an existing csv file to locate the row in which a string occurs. I am then looking to update this row with new data.

What I have so far gives me an "TypeError: unhasable type: 'list'":

allLDR = []
with open('myfile.csv', mode='rb') as f:
    reader = csv.reader(f)
    #allLDR.extend(reader)
    for num, row in enumerate(reader):
        if myField in row[0]:
            rowNum = row

line_to_override = {rowNum:[nMaisonField, entreeField, indiceField, cadastreField]}

with open('myfile.csv', 'wb') as ofile:
    writer = csv.writer(ofile, quoting=csv.QUOTE_NONE, delimiter=',')
    #for line, row in enumerate(allLDR):
    for line, row in enumerate(reader):
        data = line_to_override.get(line, row)
        writer.writerow(data)
Community
  • 1
  • 1
user25976
  • 1,005
  • 4
  • 18
  • 39

1 Answers1

1

The line allDR.extend(reader) consumes all of the input lines from the csv.reader object. Therefore, the for loop never runs, and rowNum=row is never executed, and {rowNum:blah} generates an exception.

Try commenting out the allDR.extend(reader) line.

As a debugging aid, try adding print statements inside the for loop and inside the conditional.


Here is a program which does what I think you want your program to do: it reads in myfile.csv, modifies rows conditionally based on the content of the first cell, and writes the file back out.

import csv

with open('myfile.csv', mode='rb') as ifile:
    allDR = list(csv.reader(ifile))

for row in allDR:
    if 'fowl' in row[0]:
        row[:] = ['duck', 'duck', 'goose']

with open('myfile.csv', 'wb') as ofile:
    csv.writer(ofile).writerows(allDR)
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • hm...just checking--row[0] is the first column, right? that's what i'm trying to read and i'm sure that myField exists in the first column of the csv...i'm going to try your test – user25976 May 07 '15 at 01:03
  • See recent edit for a more useful theory. In either event, `rowNum=row` is never executed. – Robᵩ May 07 '15 at 01:06
  • how do I get around allLDR being empty for the csv writer? – user25976 May 07 '15 at 01:08
  • Is the only goal of this program to modify the one line? Do you need `allDR` for any other reason? – Robᵩ May 07 '15 at 01:09
  • Does the program I posted answer your question? – Robᵩ May 07 '15 at 01:19
  • yes, i'm going to accept your answer. just another newbie question in case you want to answer: is it actually necessary to rewrite the whole csv file? Any way to do this by only targeting the row and rewriting that one? – user25976 May 07 '15 at 01:33
  • 2
    @user25976: You have to rewrite the whole file. That's how text files work. See [How to edit a file in place](http://stupidpythonideas.blogspot.com/2014/09/how-to-edit-file-in-place.html). – abarnert May 07 '15 at 01:40
  • @Rob Weird...it seems to be writing old values, actually. I didn't catch that with my hasty testing. When printing allLDR, it shows that the new values aren't taken into account – user25976 May 07 '15 at 02:34
  • Did you happen to change `row[:] = ...` to `row = ...`? That would create the behavior you see. – Robᵩ May 07 '15 at 04:13