Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reading lines 2 at a time

Tags:

python

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

like image 220
foosion Avatar asked Oct 06 '09 23:10

foosion


People also ask

How do you read multiple lines at a time in Python?

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.

How do you read 4 lines in Python?

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.

What are read 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.


1 Answers

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

like image 104
Alex Martelli Avatar answered Sep 30 '22 04:09

Alex Martelli