5

I have names.csv

first_name,last_name
Baked,Beans
Lovely,Spam
John,Bang
Harry,Potter

I want to rename "John Ban" with "jason statham" in same file. I tried to use file.seek() but failed

import csv
with open('/home/tiwari/Desktop/names.csv', 'rw+') as csvfile:
    fieldnames = ['first_name', 'last_name']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    reader = csv.DictReader(csvfile)
    for line, row in enumerate(reader):
        rs = sys.getsizeof(row)
        if row['first_name'] == 'John':
            csvfile.seek(-rs)
            writer.writerow({'first_name': 'Jason', 'last_name': 'statham'})
sujit tiwari
  • 274
  • 3
  • 14

1 Answers1

5

Your approach will not work unless the replacement string is exactly same length with the original string.

I suggest to read all rows, and replace them, and write it back.

import csv

with open('/home/tiwari/Desktop/names.csv', 'r+') as csvfile:
    reader = csv.DictReader(csvfile)

    rows = []
    for row in reader:
        if row['first_name'] == 'John':
            row['first_name'] = 'Jason'
            row['last_name'] = 'Statham'
        rows.append(row)

    csvfile.seek(0)  # back to begining of the file.
    fieldnames = ['first_name', 'last_name']
    writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
    writer.writeheader()
    writer.writerows(rows)
    csvfile.truncate()  # In case of updated content is shorter.
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • I agree with your suggestion but I have to run it for millions of records in that case storing all of them to a list is probably memory issue and extra overhead. – sujit tiwari Nov 28 '15 at 11:16
  • It will be better if we have some solution with the same reader or writer pointer. – sujit tiwari Nov 28 '15 at 11:16
  • @sujittiwari, Then you'd better to write into another file (`names2.csv` for example), then rename it to `names.csv` after writing is done. – falsetru Nov 28 '15 at 14:14
  • @sujittiwari, It's impossible to use `seek(-n, 1)` especially if the replacement string and original string lengths are different as I mentioned in the answer. – falsetru Nov 28 '15 at 14:15
  • Hi @falsetru, I am already doing that, but thought to save some write cycles. Thanks for you consideration – sujit tiwari Nov 30 '15 at 09:12