假设您打开一个文件,并在文件的某处执行 seek(),您如何知道当前文件行?
(我个人解决了一个临时文件类,该类在扫描文件后将搜索位置映射到行,但我想查看其他提示并将这个问题添加到stackoverflow,因为我无法在任何地方找到问题谷歌)
假设您打开一个文件,并在文件的某处执行 seek(),您如何知道当前文件行?
(我个人解决了一个临时文件类,该类在扫描文件后将搜索位置映射到行,但我想查看其他提示并将这个问题添加到stackoverflow,因为我无法在任何地方找到问题谷歌)
当您使用 seek() 时,python 会使用指针偏移量来跳转到文件中的所需位置。但是为了知道当前的行号,你必须检查每个字符直到那个位置。所以你不妨放弃 seek() 转而支持 read():
代替
f = open(filename, "r")
f.seek(55)
和
f = open(filename, "r")
line=f.read(55).count('\n')+1
print(line)
也许您不希望使用 f.read(num),因为如果 num 非常大,这可能需要大量内存。在这种情况下,您可以使用这样的生成器:
import itertools
import operator
line_number=reduce(operator.add,( f.read(1)=='\n' for _ in itertools.repeat(None,num)))
pos=f.tell()
这相当于f.seek(num)
给你带来了额外的好处line_number
。
以下是我解决问题的方法,尽可能使用懒惰:
from random import randint
from itertools import takewhile, islice
file = "/etc/passwd"
f = open(file, "r")
f.seek(randint(10,250))
pos = f.tell()
print "pos=%d" % pos
def countbytes(iterable):
bytes = 0
for item in iterable:
bytes += len(item)
yield bytes
print 1+len(list(takewhile(lambda x: x <= pos, countbytes(open(file, "r")))))
对于可读性稍差但更懒惰的方法,请使用enumerate
and dropwhile
:
from random import randint
from itertools import islice, dropwhile
file = "/etc/passwd"
f = open(file, "r")
f.seek(randint(10,250))
pos = f.tell()
print "pos=%d" % pos
def countbytes(iterable):
bytes = 0
for item in iterable:
bytes += len(item)
yield bytes
print list(
islice(
dropwhile(lambda x: x[1] <= pos, enumerate(countbytes(open(file, "r"))))
, 1))[0][0]+1