if I have something like the following

file = open(filename, 'rb')

for line in file:
    #do stuff

Once I find what I'm looking for in file and it's placed in the line variable, how could I then capture that position withing file, not just line?

enumerate() is great for grabbing an index and item at the same time, and f.tell() can tell you the current position in the file:

for i, line in enumerate(file):
    print('{lineno} ({pos}): {line}'.format(
        lineno=i + 1, 
        pos=file.tell(), 
        line=line))

Edited 1 Year Ago by chriswelborn: bad variable name

It is true, although I've read rumors that file.tell() is slow, at least in text mode. See Click Here for example. You can also define your own wrapper

def traverse_file(ifh):
    pos = 0
    for lineno, line in enumerate(ifh, 1):
        tmp = len(line)
        yield lineno, pos, line
        pos += tmp

with open(filename, 'rb') as ifh:
    for lineno, filepos, line in traverse_file(ifh):
        ...

Edited 1 Year Ago by Gribouillis

@Gribouillis: yeh, I don't use tell() a lot, but I can image len() being faster. I'm on my phone so I can't check, but I know yours will return the correct character position. What I'm wondering is if tell() will return the correct byte position (multibyte Unicode comes to mind). If so, each version is good for a specific use case, character position versus byte position.

If I am reading so many bytes at a time via read(number_of_bytes) or processing one line at a time via a loop, for line in file how will tell() behave? Will it still be giving me the position in the whole file or will it's positon be relative to what am processing in bytes or the current line?
I'm trying to process a .flac audio file. I need to find 'artist=', under any combination of caps or lowercase. Once I find that in the file how would I get the position of tell() to jump to the end of the '=' sign after 'artists='?
While I'm here, are there new lines in a binary files like a .flac file or is it just one giant line that only shows up as newlines for the screen?

import sys

file = open(sys.argv[1], 'rb')
tag_artist = b'artist='
artist_name = []

line = b''

position = 0
while tag_artist not in line.lower(): 
    line = file.read(15)
    print(file.tell())

print(line)
file.seek(675)
print(file.read(15))

Please do not mention other libraries that can do this for me.

This article has been dead for over six months. Start a new discussion instead.