2012-07-06 10 views
5

Necesito leer un archivo, línea por línea y tengo que echar un vistazo a 'la próxima línea' así que primero leo el archivo en una lista y luego ciclo por la lista ... de alguna manera esto parece grosero, construir la lista podría ser costoso.acceso al archivo peek ahead

for line in open(filename, 'r'): 
    lines.append(line[:-1]) 

for cn in range(0, len(lines)): 
    line = lines[cn] 
    nextline = lines[cn+1] # actual code checks for this eof overflow 

tiene que haber una mejor manera de iterar sobre las líneas, pero yo no sé cómo se asoman por delante

+2

¿Por qué necesita para echar un vistazo por delante? No está claro en su código dónde ocurre el "vistazo hacia adelante" y cómo lo usa. – unwind

+2

Dejé esa parte más adelante, era grande y no arrojaba luz sobre el problema – Paul

Respuesta

6

Usted podría estar buscando algo así como la receta pairwise de itertools.

from itertools import tee, izip 
def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = tee(iterable) 
    next(b, None) 
    return izip(a, b) 

with open(filename) as f: # Remember to use a with block so the file is safely closed after 
    for line, next_line in pairwise(f): 
     # do stuff 
+1

que es realmente agradable, no es fácil para mí en este momento, pero si me pongo de puntillas puedo tocarlo, ¡gracias! – Paul

+0

oke, obteniendo un mejor control sobre las itertools, sin embargo ... fallando en captar el significado exacto de next (b, None) ... – Paul

+1

@Paul adelanta el iterador b hacia adelante un elemento. Si no quedan elementos en un iterador, se generará 'StopIteration'. 'next' acepta un argumento predeterminado que devuelve si eso sucede, en lugar de tener el error planteado. 'None' solo se usa como marcador de posición, porque si hemos llegado al final de la iteración, de todos modos no usaremos ese valor. – jamylak

1

Se podía hacerlo de esta manera

last_line = None 

for line in open(filename):                 
    if last_line is not None: 
     do_stuff(last_line, line) 
    last_line = line               
0

puede crear una iterator y hacerlo de esta manera:

f = open(filename, 'r') 
g = open(filename, 'r') 

y = iter(g.readlines()) 
y.__next__() 

for line in f: 
    print(line) 
    try: 
     print(y.__next__()) 
    except StopIteration: 
     f.close() 
     g.close() 
+0

'g' ya es un iterador sobre las líneas del archivo, por lo que no es necesario' y'. También presumo que estás usando python 3 ya que llamaste '__next__', solo deberías usar' next (y) 'si realmente lo necesitas. No creo que sea una buena idea abrir el mismo archivo dos veces, mi solución usa 'tee' para hacer esto. También debe 'cerrar' los archivos o usar un bloque' with'. – jamylak

+0

'next (y)' no funciona en Python 3. Yg es un objeto 'TextIOWrapper'. Entonces, incluso si es un objeto iterable, no tiene el método 'next()' para. Y sí, probablemente no sea una buena idea abrir el mismo archivo dos veces, pero es solo en modo lectura, así que no creo que haga mucho daño. – Vizard

+0

Sí, usar 'tee' es probablemente un mejor enfoque, pero traté de hacerlo lo más simple posible. – Vizard

Cuestiones relacionadas