[Python-Dev] Use for enumerate() (original) (raw)

Tim Peters tim.one@comcast.net
Fri, 26 Apr 2002 20:56:31 -0400


[Guido]

Here's a cute use for enumerate(), now that it's checked in. ... A function that reads forward until the right line is of course easily written for any version of Python; but enumerate() seems a particularly good fit here since it avoids the need to have a separate counter. This also shows how useful it is that files are iterators!

def getline(filename, lineno): if lineno < 1: return '' lineno -= 1 f = open(filename) for i, line in enumerate(f): if i == lineno: break else: line = '' f.close() return line Challenge 1: do it faster.

Challenge 0: Stop posting Python code with stinking tabs .

The attached g2 is about 60% quicker across the text files I tried it on, using this timing driver (which sums the time across all interesting inputs; note that, overall, this is quadratic-time in the number or lines for either method):

FNAME = "whatever"

def drive(): from time import clock as now f = file(FNAME) n = len(f.readlines()) f.close() indices = range(n+2)

for func in getline, g2:
    start = now()
    for i in indices:
        func(FNAME, i)
    finish = now()
    print func.__name__, finish - start

Challenge 2: do it with less code.

Measured by bytes, lines, statements, or conceptual pain ?

Challenge 3: do it faster and with less code.

That's a tough one.

Here's g2. It's a non-ambitious member of the "reduce the number of trips around the eval loop" school of optimization:

def g2(filename, lineno): offset = lineno - 1 if offset < 0: return '' line = '' f = file(filename) lines = True while lines: lines = f.readlines(5000) n = len(lines) if offset >= n: offset -= n continue line = lines[offset] break f.close() return line