[Tutor] better looping construct for replacing elements in file?

Peter Otten __peter__ at web.de
Thu Feb 2 23:04:23 CET 2012


Brett Longworth wrote:

> Hello,
> 
> Today I wrote a quick script to replace elements in multiple lines of a
> file with corresponding elements from a single line in another file,
> linking the two via an index element. The code iterates through the
> entire source file to find the matching index for each line of the
> destination file. This works, but it's clearly a terrible way to solve
> the problem. Can someone point me to a more efficient, pythonic solution?
> 
> thanks,
> -Brett
> 
> Code:
> 
> wheel = "A794"
> wheelfile = "A794.txt"
> statusfile = "CURRENT.ams"
> 
> sfile = csv.reader(open(statusfile), delimiter='\t')
> statusWriter = csv.writer(open('statustest.txt', 'wb'), delimiter='\t',
> quotechar='|', quoting=csv.QUOTE_MINIMAL)
> 
> for sline in sfile:
>    #print sline
>    wfile = csv.reader(open(wheelfile))
>    for line in wfile:
>      #print line[0]
>      #print sline[18]
>      if line[0] == sline[18]:
>        sline[0] = line [1]
>        sline[1] = "OSG"+str(line[4])
>        sline[17] = wheel
>        sline[21] = line[9]
>        statusWriter.writerow(sline)

You could put the data from wheelfile into a dictionary with the first 
column as the key, something like

import csv
from contextlib import contextmanager
from functools import partial

@contextmanager
def manager(mode, process, filename, **kw):
    with open(filename, mode) as f:
        yield process(f, **kw)

reader = partial(manager, "rb", csv.reader)
writer = partial(manager, "wb", csv.writer)

wheel = "A794"
wheelfilename = "A794.txt"
statusfilename = "CURRENT.ams"

wheel_lookup = {}
with reader(wheelfilename) as rows:
    for row in rows:
        key = row[0]
        if key in wheel_lookup:
            raise ValueError("duplicate key {}".format(key))
        lookup[key] = row

with reader(statusfilename, delimiter="\t") as status_rows:
    with writer("statustest.txt", delimiter="\t") as dest:
        for status_row in status_rows:
            key = status_row[18]
            if key in lookup:
                wheel_row = wheel_lookup[key]
                status_row[0] = wheel_row[1]
                status_row[1] = "OSG{}".format(wheel_row[4])
                status_row[17] = wheel
                status_row[21] = wheel_row[9]
                dest.writerow(status_row)


I hope I didn't confuse the files or columns...



More information about the Tutor mailing list