When using readline() in python is it possible to specify what line to read? When I run the following code, I get lines 1,2,3 but I would like to read lines 2,6,10
def print_a_line(line, f):
print f.readline(line)
current_file = open("file.txt")
for i in range(1, 12):
if(i%4==2):
print_a_line(i, current_file)
No, you can't use readline that way. Instead, skip over the lines you don't want. You have to read through the file because you can't know ahead of time where to seek to to read a specific line (unless the newlines appear in some regular offset). You can use enumerate to determine what line you're on, so you only have to read the file once and can stop after the location you don't care about.
with open('my_file') as f:
for i, line in enumerate(f, start=1):
if i > 12:
break
if i % 4 == 0:
print(i, line)
If you know that each line is a certain byte length, you can seek to the specific position for a given line, rather than iterating over the lines.
line_len = 20 # bytes
with open('my_file', 'rb') as f:
for i in range(0, 13, 4):
f.seek(i * line_len)
print(f.read(line_len).decode())
You can use the consume recipe from itertools, which is one of the fastest ways to skip lines:
from itertools import islice
from collections import deque
def consume(iterator, n):
"Advance the iterator n-steps ahead. If n is none, consume entirely."
# Use functions that consume iterators at C speed.
if n is None:
# feed the entire iterator into a zero-length deque
deque(iterator, maxlen=0)
else:
# advance to the empty slice starting at position n
next(islice(iterator, n, n), None)
with open("in.txt") as f:
l = []
sm = 0
for i in (2, 6, 10):
i -= sm
consume(f, i-1)
l.append(next(f, ""))
sm += i
We just need to subtract what we have already consumed so we keep the lines matching each i. You can put the code in a function and yield each line:
def get_lines(fle,*args):
with open(fle) as f:
l, consumed = [], 0
for i in args:
i -= consumed
consume(f, i-1)
yield next(f, "")
consumed += i
To use just pass the filename and the line numbers:
test.txt:
1
2
3
4
5
6
7
8
9
10
11
12
Output:
In [4]: list(get_lines("test.txt",2, 6, 10))
Out[4]: ['2\n', '6\n', '10\n']
In [5]: list(get_lines("stderr.txt",3, 5, 12))
Out[5]: ['3\n', '5\n', '12']
If you only wanted a single line you could also use linecache:
import linecache
linecache.getline("test.txt",10)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With