多次迭代文件

时间:2015-03-18 23:08:48

标签: python

我有一个文件,其中每一行都是一个数字:

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

我不知道如何多次遍历第二个文件。当我从第一个文件中获取第一个值并在第二个文件中查找它时,它会搜索第二个文件,并且永远不会再次重复它。

2 个答案:

答案 0 :(得分:1)

使用seek()。完成文件一次后,执行[fileobject] .seek(),然后再次浏览该文件。

此外,默认情况下,seek()将转到文件的开头,如果您希望文件中的特定点可以传递参数。

答案 1 :(得分:0)

可以在文件中多次迭代(您可以通过调用thefile.seek()将文件重置为开头),但可能非常代价高昂。

让我们说一般来说,你有一个函数来识别给定一行的键号,例如

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的文件更快! - )