2017-03-16 381 views
2

我必须读取文件的最后4行。如何读取python中最后几行?

我试过如下:

top_tb_comp_file = open('../../ver/sim/top_tb_compile.tcl', 'r+') 
top_tb_comp_end = top_tb_comp_file.readlines()[:-4] 
top_tb_comp_file.close() 

没有工作(我得到top_tb_comp_end文件的第一行)。

回答

1

您的索引是错误的。随着[:-4],你要求与你真正想要的完全相反。

尝试以下操作:

top_tb_comp_file = open('../../ver/sim/top_tb_compile.tcl', 'r+') 
top_tb_comp_end = top_tb_comp_file.readlines()[-4:] 
# you noticed that the '-4' is now before the ':' 
top_tb_comp_file.close() 

编辑

感谢@Noctis,我已经围绕这个问题做了标杆。关于速度和内存使用情况的collection.deque选项和file.readlines一。

通过@Noctis提出的collection选项似乎是在内存使用速度的长期更好:在我的结果,我在这没有在该行collections.deque(file, 4)发生的临界线file.readlines()[-4:]观察存储器利用的小高峰。此外,我重复了文件读取阶段的速度测试,在这种情况下,collections选项似乎也更快。

我已经遇到了一些问题,用SO渲染来显示这段代码的输出,但是如果你安装包memory_profilerpsutil你应该可以自己看到(大文件)。

import sys 
import collections 
import time 

from memory_profiler import profile 


@profile 
def coll_func(filename): 
    with open(filename) as file: 
     lines = collections.deque(file, 4) 
    return 0 


@profile 
def indexing_func(filename): 
    with open(filename) as file: 
     lines = file.readlines()[-4:] 
    return 0 


@profile 
def witness_func(filename): 
    with open(filename) as file: 
     pass 
    return 0 


def square_star(s_toprint, ext="-"): 
    def surround(s, ext="+"): 
     return ext + s + ext 

    hbar = "-" * (len(s_toprint) + 1) 
    return (surround(hbar) + "\n" 
      + surround(s_toprint, ext='|') + "\n" 
      + surround(hbar)) 

if __name__ == '__main__': 

    s_fname = sys.argv[1] 
    s_func = sys.argv[2] 

    d_func = { 
     "1": coll_func, 
     "2": indexing_func, 
     "3": witness_func 
    } 

    func = d_func[s_func] 

    start = time.time() 
    func(s_fname) 
    elapsed_time = time.time() - start 

    s_toprint = square_star("Elapsed time:\t{}".format(elapsed_time)) 

    print(s_toprint) 

只需键入以下内容:

python3 -m memory_profiler profile.py "my_file.txt" n 

n是1,2或3。

1

下面的示例打开一个名为names.txt文件并打印的最后4个文件中的行。应用于你的例子,你只需要拿走第2,第5和第7行给出的模式。其余的很简单。

#! /usr/bin/env python3 
import collections 


def main(): 
    with open('names.txt') as file: 
     lines = collections.deque(file, 4) 
    print(*lines, sep='') 


if __name__ == '__main__': 
    main() 
+0

谢谢你的诀窍,但我不确定它真的值得。一个更好的索引似乎对我来说更简单和实际速度更快是: '在[6]:进口集合 在[7]:清单当然=列表(范围(1000000)) 在[8]:%timeit线=在[9]中:%timeit lines = liste [-4:] 10000000个循环,最好是3:每个循环115纳秒[4] 100个循环,最好3个:每个循环8.95 ms – LucG

+0

如果在两种方法上运行内存配置文件会发生什么情况? –

+0

我不知道该怎么做。你能自己做,并分享你的结果吗? – LucG