質問

ファイルを開いて、ファイルのどこかでseek()を実行するとします。現在のファイル行をどのように知るのですか?

(ファイルをスキャンした後、シーク位置を行にマップするアドホックファイルクラスで個人的に解決しましたが、他のヒントを参照し、この質問をstackoverflowに追加したかったので、 Googleのどこでも問題)

役に立ちましたか?

解決

可能な限り怠lazを使用して、問題にアプローチする方法は次のとおりです。

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")))))

読みやすさはやや劣りますが、より怠laなアプローチには、 enumerate および 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

他のヒント

seek()を使用すると、Pythonはポインターオフセットを使用してファイル内の目的の位置にジャンプします。ただし、現在の行番号を知るには、その位置まで各文字を調べる必要があります。したがって、read()を優先してseek()を放棄することもできます。

交換

f = open(filename, "r")
f.seek(55)

with

f = open(filename, "r")
line=f.read(55).count('\n')+1
print(line)

おそらく、numが非常に大きい場合、f.read(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 を提供するという利点があります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top