bassmann
bassmann

Reputation: 260

modifying a csv file creates unwanted duplicate output using seek(0) method

I’m trying to make the following adjustments to my csv file. - Action 1 - Insert a column and fill with a variable - Action 2 - Delete first 32 rows of the file I’ve tried to reset the file position with seek() method to achieve this.

When run, the csv file inserts my column variable via action 1. Action 2 appends a duplicate set of records less the 32 deletions with no column inserted.

What I want is the 2 actions applied to the original dataset. I’m thinking seek) might not be what I need. What else should I consider? N.b. data files are small

My Code;

with open(temp_filename, 'r', newline='') as inf, \
    open(local_filename, 'w', newline='') as outf:
    reader = csv.reader(inf)
    writer = csv.writer(outf)
    all = []
    row = next(reader)

# insert column and fill
    for row in (reader):
        all.append([str(ASXCode)] + row)  
    writer.writerows(all)

    inf.seek(0)

# delete first 32 rows 
    for _ in range(32):   # skip first 32 rows
        next(reader)      
    writer.writerows(reader)  # copy the rest

Upvotes: 1

Views: 453

Answers (2)

Jamie Bull
Jamie Bull

Reputation: 13539

Given that the changes are intended to happen in place, and your files are small, how about:

with open('test.csv', 'r') as inf:
    reader = csv.reader(inf)
    lines = [[ASXCode] + row for row in list(reader)[32:]]

with open('test.csv', 'w') as outf:
    writer = csv.writer(outf)
    writer.writerows(lines)

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1123830

You could just skip the 32 rows and never process those, there is no need to 'delete' those from your output that way.

Add the column as you copy the data across to the other file:

from itertools import islice

with open(temp_filename, 'r', newline='') as inf, \
        open(local_filename, 'w', newline='') as outf:
    reader = csv.reader(inf)
    writer = csv.writer(outf)
    next(islice(reader, 32, 32), None)  # skip 32 rows

    # write to output file with extra column
    for row in (reader):
        writer.writerow([str(ASXCode)] + row)

You only need to seek if you have to re-read all the data from the file, but you rarely really need to do that. As an alternative to skipping, you could just have removed 32 entries from the all list, for example, before writing to the output CSV; del all[:32] would have done that for you.

Upvotes: 1

Related Questions