2015-03-18 70 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