TheMapSmith
TheMapSmith

Reputation: 35

Return lines from file in order of a list

I've tried to put together a solution from similar questions but have failed miserably. I just don't know enough about Python yet :(

I have an inputlist containing elements in a particular order ex: ["GRE", "KIN", "ERD", "KIN"]

I have a datafile containing the elements, plus other data ex:

"ERD","Data","Data"...  
"KIN","Data","Data"...  
"FAC","Data","Data"...  
"GRE","Data","Data"...  

I need to create an outputlist that contains the lines from the datafile in the order they appear in the inputlist.

The code below returns the outputlist in the order the appear in the datafile, which is not the intended behavior... :-\

with open(inputfile, 'r') as f:
    names = [line.strip() for line in f]

outputlist = []

with open(datafile, 'r') as f:
    for line in f:
        name = line.split(',')[0]
        if name[1:-1] in names: 
            outputlist.append(line)
    output = open(outputfile, 'w')
    output.writelines(outputlist)

How can I have it return the list in the proper order? Thanks in advance for your help :-)

Edit

Thank's to Oscar, this is the solution I implemented:

datafile = 'C:\\testing\\bldglist.txt'
inputfile = 'C:\\testing\\inputlist.txt'
outputfile = "C:\\testing\\output.txt"

with open(inputfile, 'r') as f:
    inputlist = [line.strip() for line in f]

def outputList(inputlist, datafile, outputfile):
    d = {}
    with open(datafile, 'r') as f:
        for line in f:
            line = line.strip()
            key = line.split(',')[0]
            d[key] = line
    with open(outputfile, 'w') as f:
        f.write('"Abbrev","Xcoord","Ycoord"\n')
        for key in inputlist:
            f.write(d[key] + '\n')

outputList(inputlist, datafile, outputfile)

Upvotes: 2

Views: 170

Answers (3)

Óscar López
Óscar López

Reputation: 236004

Assuming a data file with this format:

"ERD","Data","Data"...  
"KIN","Data","Data"...  
"FAC","Data","Data"...  
"GRE","Data","Data"... 

Try this solution:

def outputList(inputlist, datafile, outputfile):
    d = {}
    with open(datafile, 'r') as f:
        for line in f:
            line = line.lstrip()
            key = line.split(',')[0]
            d[key] = line
    with open(outputfile, 'w') as f:
        for key in inputlist:
            f.write(d[key])

Use it like this:

outputList(['"GRE"', '"KIN"', '"ERD"', '"KIN"'],
           '/path/to/datafile',
           '/path/to/outputfile')

It will write the output file with the expected order.

Upvotes: 1

Katriel
Katriel

Reputation: 123632

This is the easy solution. It reads the entire input file into memory as a dictionary of first letter: line. It's then easy to write the lines in the write order.

If the file is very large (gigabytes) or you don't have a lot of memory, there are other ways. But they're not nearly as nice.

I haven't tested this.

import csv

data = {}
with open(datafile) as f:
    for line in csv.reader(f):
        data[line[0]] = line

with open(outputfile, "w") as f:
    f = csv.writer(f)
    for entry in inputlist:
        f.writerow(data[entry])

Upvotes: 5

dawg
dawg

Reputation: 103764

1) Create a list with the elements you wish to map to. In this case, ["GRE", "KIN", "ERD", "FAC"]

2) Read the file and map (using a dictionary of lists) the first elements.

3) Output to a file.

import csv

out_index=["GRE", "KIN", "ERD", "FAC"]
d={}
with open('/Users/andrew/bin/SO/abcd.txt','r') as fr:
    for e in csv.reader(fr):
        if e[0] not in d: d[e[0]]=[]
        for ea in e[1:]:
            d[e[0]].append(ea)

for i in out_index:
    print i,":"
    for e in d[i]:
        print '   ',e

Given this example data:

"ERD","Data-a1","Data-a2"
"KIN","Data-b1","Data-b2"
"FAC","Data-c1","Data-c2"
"GRE","Data-d1","Data-d2"
"ERD","Data-a3","Data-a4"
"GRE","Data-d3","Data-d4"

Output:

GRE :
    Data-d1
    Data-d2
    Data-d3
    Data-d4
KIN :
    Data-b1
    Data-b2
ERD :
    Data-a1
    Data-a2
    Data-a3
    Data-a4
FAC :
    Data-c1
    Data-c2

Done!

Upvotes: 0

Related Questions