【问题标题】:How to read first line of a file twice?如何两次读取文件的第一行?
【发布时间】:2015-09-22 21:40:48
【问题描述】:

我有一个包含很多行的大文件,我想先读取第一行,然后再从第一行开始循环遍历所有行。

我首先认为类似的事情会做到这一点:

file = open("fileName", 'r')
first_line = file.readline()
DoStuff_1(first_line)

for line in file:
   DoStuff_2(line)

file.close()

但是这个脚本的问题是传递给DoStuff_2 的第一行是第二行而不是第一行。我对 file 是什么类型的对象没有很好的直觉。我认为它是一个迭代器,并不真正知道如何处理它。我发现的不好的解决方案是

file = open("fileName", 'r')
first_line = file.readline()

count = 0
for line in file:
   if count == 0:
      count = 1
      DoStuff_1(first_line)
   DoStuff_2(line)

file.close()

但它非常愚蠢,而且计算成本有点高,因为它在每次迭代时都运行一个 if 语句。

【问题讨论】:

  • open 在 python 中返回一个生成器。 :P

标签: python file iterator


【解决方案1】:

你可以这样做:

with open('fileName', 'r') as file:
    first_line = file.readline()
    DoStuff_1(first_line)
    DoStuff_2(first_line)

    # remaining lines
    for line in file:
        DoStuff_2(line)

请注意,我将您的代码更改为使用 with,因此 file 会自动关闭。

【讨论】:

  • 哈哈,这太明显了!我想当您处于更复杂的代码中间时,您会错过显而易见的事情,但是一旦将问题简化为问题的基本要素,答案就会非常明显。谢谢你。我没有使用with,因为我不知道file 对象是否会存在于with 函数中调用的每个函数的环境中。是吗?我目前刚刚将file 定义为全局。
  • @Remi.b 在我看来,这就是 Stack Overflow 的目的:让其他人看到我们的盲点。至于with的使用:我只是假设你问题中的使用是第一次分配file,在这种情况下使用with是一个好习惯。如果在其他地方也使用了file,您将需要更多地了解要使用的确切解决方案。
【解决方案2】:

我想使用生成器来抽象您的一般控制流。比如:

def first_and_file(file_obj):
    """
    :type file_obj: file
    :rtype: (str, __generator[str])
    """
    first_line = next(file_obj)

    def gen_rest():
        yield first_line
        yield from file_obj

    return first_line, gen_rest()

在 Python 2.7 中,将 yield from 替换为:

for line in file_obj:
    yield line

【讨论】:

    【解决方案3】:

    另一个答案是打开文件两次。

    with open("file.txt", "r") as r:
        Do_Stuff1(r.readline())
    
    with open("file.txt", "r") as r:
        for line in r:
            Do_Stuff2(line)
    

    【讨论】:

      【解决方案4】:

      此问题的一般情况的解决方案之一是保存您所在的行号。在完成需要您相对于当前行转到上一行的操作后,通过执行 file.seek(0) 使用行号变量,然后循环 file.readline() 所需的次数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-24
        • 2011-10-25
        • 2017-02-12
        • 2016-05-09
        • 2014-12-10
        • 2011-08-15
        • 1970-01-01
        相关资源
        最近更新 更多