2015-03-18 93 views
0

我有一個文件,其中每行是一個數字:迭代通過文件多次

567 
345 
456 
123 

第二個文件具有相同的數字,像這樣的行:

something1 123 something2 
something3 345 something4 
something5 456 something6 
something7 567 something7 

所以,第二個文件的數字是有序的,第一個文件沒有。我想重新排序第二個文件是這樣的:

something7 567 something7 
something3 345 something4 
something5 456 something6 
something1 123 something2 

我不知道如何遍歷第二個文件多次。當我從第一個文件中獲取第一個值並在第二個文件中查找它時,它將搜索第二個文件,並且不會再次重新遍歷它。

+0

[f.seek()和f.tell()t o閱讀文本文件的每一行](http://stackoverflow.com/questions/15594817/f-seek-and-f-tell-to-read-each-line-of-text-file) – ha9u63ar 2015-03-18 23:11:18

+0

請不要只是要求我們爲你解決問題。告訴我們你是如何試圖自己解決問題的,然後向我們展示結果是什麼,並告訴我們爲什麼你覺得它不起作用。請參閱「[您嘗試過什麼?](http://whathaveyoutried.com/)」,以獲得一篇您最近需要閱讀的優秀文章。 – 2015-03-19 01:25:09

回答

0

通過文件遍歷多次是可能的(您可以通過調用thefile.seek()來重置文件,但可能是昂貴。

比方說,你有一個函數來確定給定行鍵號一般性,e.g

def getkey(line): 
    return line.split()[1] 
在你的例子,其中的關鍵是在三號線空格分開的話第二

。現在,如果對第二個文件中的數據將舒適地適合RAM(所以到幾GB - 認爲這將需要多長時間重複幾百次對 - !)...:

key2line = {} 
with open(secondfile) as f: 
    for line in f: 
     key2line[getkey(line)] = line 

with open(firstfile) as f: 
    order = [line.strip() for line in f] 

with open(outputfile, 'w') as f: 
    for key in order: 
     f.write(key2line[key]) 

現在是不是一個非常明確和有效的方法...?

如果第二個文件太大了一個小的因素,比如說10倍左右,你實際上可以放進內存中的東西,那麼你仍然可以在文件中大量跳轉的情況下解決它,通過使用尋找和告訴。

第一個環路將成爲:

key2offset = {} 
with open(secondfile) as f: 
    offset = 0 
    for line in f: 
     new_offset = f.tell() 
     key2line[getkey(line)] = offset 
     offset = new_offset 

和最後一個循環將成爲:

with open(secondfile) as f: 
    with open(outputfile, 'w') as f1: 
     for key in order: 
      f.seek(key2offset[key]) 
      line = f.readline() 
      f1.write(line) 

複雜一點,慢 - 但仍然方式比重新快 - 讀數十億次,一遍又一遍,一個數十GB的文件!)

0

看看使用seek()。一旦完成了一次文件,請執行[fileobject] .seek(),然後您可以再次通過該文件。

此外,seek()默認會轉到文件的開頭,如果您想要文件中的某個點可以傳遞參數。

+0

我不太瞭解seek()的工作原理。我會仔細看看的。 – user20150316 2015-03-18 23:25:21

+0

我不明白如何查找線路號碼並與之匹配 – user20150316 2015-03-18 23:26:55