我想在我的 Python 脚本中一次读取一个文件。另外,我想在这样做时跳过第一行。
我能想到几个办法:
1.
with open('file name', 'r') as fh:
fh.readline()
lines = fh.readlines()
with open('file name', 'r') as fh:
lines = fh.readlines()
del lines[0]
with open('file name', 'r') as fh:
lines = fh.readlines()[1:]
请告诉我你的想法。如果您能提供任何参考资料,那就太好了。
请注意,我不是在寻找跳过第一行的方法。可以看出,我已经有 3 种方法可以做到这一点。我正在寻找的是最有效的方法和原因。可能我没有列出最有效的方法。
我相信
#1 可能是最有效的,因为偏移量会被 readline 移过第一行,然后我们只读取其余的行。
#2:不太确定它是将所有元素移动一个还是只移动指针。
#3:这将涉及创建另一个列表,这可能是效率最低的。
我同意您的评估,即#1 是所提出问题中最有效的方法。
为什么?因为它只读取文件一次并跳过第一行(使用 readline()) 然后读取剩余的行。不需要创建一些额外的 DS - list 然后删除第一行(如 #2),也不需要像 #3 那样创建切片。
在 ipython 中使用
%%timeit
进行了有限的测试,样本数据只有 1000 行长,#1 确实看起来确实是最快的,但它可以忽略不计。
要确定不同代码块之间的相对性能,您需要分析相关代码。分析给定函数或短代码片段的最简单方法之一是在 ipython 中使用
%timeit
“魔术”命令。
对于这个测试,我使用了以下样本数据:
chars = [chr(c) for c in range(97, 123)]
line = ','.join(c * 5 for c in chars)
# 'aaaaa,bbbbb,ccccc,ddddd,eeeee,fffff,ggggg,hhhhh,iiiii,jjjjj,kkkkk,lllll,mmmmm,nnnnn,ooooo,ppppp,qqqqq,rrrrr,sssss,ttttt,uuuuu,vvvvv,wwwww,xxxxx,yyyyy,zzzzz'
with open('test.txt', 'w', encoding='utf-8') as f:
f.write('\n'.join(line for _ in range(1000)))
两次(并列)最快的尝试:
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... next(f)
... data = f.readlines()
...
166 µs ± 185 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... f.readline()
... data = f.readlines()
...
166 µs ± 146 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
你的另外两个例子稍微慢一点:
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... data = f.readlines()[1:]
...
177 µs ± 5.06 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... data = f.readlines()
... del data[0]
...
168 µs ± 893 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
我尝试过的其他一些方法:
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... data = f.read().splitlines()
... del data[0]
...
179 µs ± 671 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... data = f.read().splitlines()[1:]
...
179 µs ± 291 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... data = f.read().split('\n', 1)[1].splitlines()
...
181 µs ± 1.16 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... data = [line for line in f][1:]
...
178 µs ± 85.7 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... next(f)
... data = [line for line in f]
...
174 µs ± 748 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... next(f)
... data = list(f)
...
167 µs ± 315 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
请注意,尽管这些方法之间的差异实际上可以忽略不计,而且运行时间可能因试验而异。在第一次运行中并列最快的方法在后来的运行中速度较慢:
>>> %%timeit
... with open('test.txt', 'r', encoding='utf-8') as f:
... next(f)
... data = f.readlines()
...
172 µs ± 4.09 µs per loop (mean ± std. dev. of 7 runs, 10,000 loops each)
请注意,过早的优化是万恶之源——如果这不是您程序中的主要瓶颈(如分析代码所揭示的那样),那么不值得花很多时间在上面。
我建议查看更多有关如何分析代码的资源: