Python: itertools.islice在循环中无效
我有这样的代码:
#opened file f
goto_line = num_lines #Total number of lines
while not found:
line_str = next(itertools.islice(f, goto_line - 1, goto_line))
goto_line = goto_line/2
#checks for data, sets found to True if needed
第一次运行时,line_str 是正确的,但之后每次运行都读取了错误的行。
举个例子,goto_line 一开始是 1000。它能正确读取第 1000 行。然后在下一次循环中,goto_line 变成了 500,但它并没有读取第 500 行,而是读取了离 1000 更近的某一行。
我想在一个大文件中读取特定的行,而不想读取多余的内容。有时候它会跳回到之前的某一行,有时候又会跳到后面的行。
我试过使用 linecache,但我通常不会在同一个文件上多次运行这段代码。
2 个回答
0
你不能这样做(也许根据文件的打开方式,有其他方法)。标准的文件迭代器(其实大多数迭代器——Python的迭代器协议只支持向前迭代)只能向前移动。所以在读取了k
行之后,再读取k/2
行实际上是读取了k+k/2
行。
你可以尝试把整个文件读入内存,但如果数据量很大,可能会占用太多内存。你也可以使用file.seek
来在文件中滚动,但这还是挺麻烦的。也许你可以使用内存映射文件?不过这只有在每行大小固定的情况下才行。如果需要的话,你可以提前计算出想要检查的行号,并在一次迭代中保存所有这些行(如果我没记错的话,应该不会太多,大约是int(log_2(line_count)) + 1
)。这样你就不需要在读取完整个文件后再回滚了。
6
Python中的迭代器只能使用一次。这一点通过例子最容易理解。下面的代码
from itertools import islice
a = range(10)
i = iter(a)
print list(islice(i, 1, 3))
print list(islice(i, 1, 3))
print list(islice(i, 1, 3))
print list(islice(i, 1, 3))
会输出
[1, 2]
[4, 5]
[7, 8]
[]
切片操作总是从上次停止的地方开始。
让你的代码正常工作的最简单方法是使用 f.readlines()
来获取文件中的所有行,然后用普通的Python列表切片 [i:j]
。如果你真的想用 islice()
,你可以每次都从头开始读取文件,方法是使用 f.seek(0)
,但这样做会非常低效。