【问题标题】:In Python, how to test whether a line is the last one?在Python中,如何测试一行是否是最后一行?
【发布时间】:2013-08-26 17:30:41
【问题描述】:

假设我要处理文件的每一行,但最后一行需要特殊处理:

with open('my_file.txt') as f:
    for line in f:
        if <line is the last line>:
            handle_last_line(line)
        else:
            handle_line(line)

问题是,如何实现? Python中似乎没有检测文件结尾的功能。

除了将行读入列表(使用 f.readlines() 或类似方法)之外,还有其他解决方案吗?

【问题讨论】:

    标签: python


    【解决方案1】:

    处理上一行

    with open('my_file.txt') as f:
        line = None
        previous = next(f, None)
        for line in f:
            handle_line(previous)
            previous = line
    
        if previous is not None:
            handle_last_line(previous)
    

    当循环终止时,你知道最后一行刚刚被读取。

    通用版本,让您分别处理最后 N 行,使用 collections.deque() object:

    from collections import deque
    from itertools import islice
    
    with open('my_file.txt') as f:
        prev = deque(islice(f, n), n)
        for line in f:
            handle_line(prev.popleft())
            prev.append(line)
    
        for remaining in prev:
            handle_last_line(remaining)
    

    【讨论】:

    • 为了便于阅读,是否值得将其嵌套到forelse 中?
    • 更一般地说,您可以使用队列来实现任意大小的处理延迟。
    • @AdamBurry 正如我在回答中所展示的,使用itertools.tee 更容易。
    • @Josh:带有for 循环的else: 套件只有在您在循环中使用break 时才能真正使用;它被称为 always 否则(即使循环迭代是空的)。我个人觉得在这里使用else 不会提高可读性。
    • @MartijnPieters 很公平,只是我的 2 美分 :)
    【解决方案2】:

    您可以使用itertools.tee 来迭代一个可迭代对象的两个副本:

    next_lines, lines = itertools.tee(file_object)
    next(next_lines)
    for next_line, line in zip(next_lines, lines):
        handle_line(line)
    last_line = next(lines, None)
    if last_line is not None:
        handle_last_line(last_line)
    

    【讨论】:

    • 您的最后一行处理可能更简单;就做for last_line in lines: handle_last_line(last_line)
    • @MartijnPieters 我认为,尽管它更短,但它的可读性并不高。 for 循环最多可以执行一次可能并不明显。当然,它允许像您的示例一样使用deque 进行泛化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多