2012-03-25 17 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 

完成!