2012-03-25 18 views
2

我试图将类似问题的解决方案放在一起,但失败了。我只是不知道有足够的了解Python的又:(按列表顺序从文件中返回行

我有一个特定的顺序的前一个inputlist包含元素:["GRE", "KIN", "ERD", "KIN"]

我有一个datafile含有的元素,再加上其他数据例如:

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

我需要创建一个包含在它们出现在inputlist顺序从datafile行的outputlist

的下面的代码返回在出现在datafile的顺序,这不是预期的行为outputlist ...: - \

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) 

我怎样才能把它以适当的顺序返回列表?在此先感谢您的帮助:-)

编辑

感谢的奥斯卡,这是我实现的解决方案:

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) 
+2

数据文件有多大?如果它很容易适应内存,则可以先从数据文件中创建一个字典。 – 2012-03-25 17:52:47

+1

如果没有,就有'搁置'。 – 2012-03-25 17:55:27

+0

这些都是非常小的文本文件,''datafile'中只有164行' – TheMapSmith 2012-03-25 18:28:23

回答

1

假设这种格式的数据文件:

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

尝试这种解决方案:

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]) 

使用方法如下:

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

它会写输出文件预期的顺序。

+0

感谢您的回复。我微调了我的问题。我用A,B,C,D作为示例,使订单问题更易于查看。这些行实际上以3个字母代码开始,就像您现在看到的那样。 – TheMapSmith 2012-03-25 18:29:29

+0

@SteveS我的解决方案的工作原理相同,代码长度为一个或三个字符无关紧要 – 2012-03-25 18:31:19

+1

让它工作!美丽。再次感谢:) – TheMapSmith 2012-03-25 18:58:48

5

这是最简单的解决方案。它将整个输入文件作为第一个字母:行的字典读入内存。在写入顺序中写入行很容易。

如果文件是非常大大(千兆字节)或者您没有很多内存,还有其他方法。但他们几乎没有那么好。

我还没有测试过这个。

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]) 
+0

感谢您的回复。我稍微修改了我的问题。我用A,B,C,D作为示例,使订单问题更易于查看。这些行实际上以3个字母代码开始,就像您现在看到的那样。当我用我的数据运行你的代码时,它返回'KeyError:'“PAR”'' – TheMapSmith 2012-03-25 18:26:57

+0

谢谢Niklas。我最终成功实施了奥斯卡的解决方案,但是这次获得了更多的选票。出于好奇,是什么让这个更好? – TheMapSmith 2012-03-25 19:02:54

+0

@Steve S:这是第一个,另一个答案基本上复制它(至少它使用完全相同的逻辑)。这个答案实际上更好,因为它使用了适当的CSV解析器。我在这个版本中修正了一个小错误,所以如果你愿意,你也可以使用它。 – 2012-03-25 19:37:21

0

1)用你想要映射的元素创建一个列表。在这种情况下,["GRE", "KIN", "ERD", "FAC"]

2)读取文件并映射(使用列表字典)第一个元素。

3)输出到文件。

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 

鉴于此示例数据:

"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" 

输出:

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 

完成!