Is there a better way to read lines two at a time from a file in python than:
with open(fn) as f:
for line in f:
try:
line2 = f.next()
except StopIteration:
line2 = ''
print line, line2 # or something more interesting
I'm in 2.5.4. Anything different in newer versions?
EDIT: a deleted answer noted: in py3k you'd need to do next(f) instead of f.next(). Not to mention the print change
Method 2: linecache package The linecache package can be imported in Python and then be used to extract and access specific lines in Python. The package can be used to read multiple lines simultaneously.
readlines() is used to read all the lines at a single go and then return them as each line a string element in a list. This function can be used for small files, as it reads the whole file content to the memory, then split it into separate lines.
The readlines() method returns a list containing each line in the file as a list item. Use the hint parameter to limit the number of lines returned. If the total number of bytes returned exceeds the specified number, no more lines are returned.
import itertools
with open(fn) as f:
for line, line2 in itertools.izip_longest(f, f, fillvalue=''):
print line, line2
Alas, izip_longest
requires Python 2.6 or better; 2.5 only has izip
, which would truncate the last line if f
has an odd number of lines. It's quite easy to supply the equivalent functionality as a generator, of course.
Here's a more general "N at a time" iterator-wrapper:
def natatime(itr, fillvalue=None, n=2):
return itertools.izip_longest(*(iter(itr),)*n, fillvalue=fillvalue)
itertools
is generally the best way to go, but, if you insisted on implementing it by yourself, then:
def natatime_no_itertools(itr, fillvalue=None, n=2):
x = iter(itr)
for item in x:
yield (item,) + tuple(next(x, fillvalue) for _ in xrange(n-1))
In 2.5, I think the best approach is actually not a generator, but another itertools-based solution:
def natatime_25(itr, fillvalue=None, n=2):
x = itertools.chain(iter(itr), (fillvalue,) * (n-1))
return itertools.izip(*(x,)*n)
(since 2.5 doesn't have the built-in next
, as well as missing izip_longest
).
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