2010-04-07 21 views
17

Esto podría ser una pregunta muy tonta, sin embargo, he buscado en línea, etc. Y no he visto una respuesta sólida.¿Cómo puedo omitir el elemento actual y el siguiente en un ciclo de Python?

¿Hay una manera simple de hacer algo como esto?

lines = open('something.txt', 'r').readlines() 
for line in lines: 
    if line == '!': 
     # force iteration forward twice 
     line.next().next() 
    <etc> 

Es fácil de hacer en C++; simplemente incremente el iterador un tiempo extra. ¿Hay alguna manera fácil de hacerlo en Python?

Me gustaría señalar, el principal objetivo de esta pregunta no es sobre "leer archivos y cosas así" y omitir cosas. Estaba buscando más iteración de estilo de iterador de C++. Además, el nuevo título es algo tonto, y realmente no creo que refleje la naturaleza de mi pregunta.

+5

Ligeramente OT, pero que no necesitan la llamada a 'readlines()' a menos que realmente desea almacenar el archivo completo en una lista de líneas. 'open()' ya devuelve un iterador que da acceso a las líneas individuales. –

+0

No lo sabía. Gracias – UberJumper

+0

yup, eso es cierto a menos que esté usando Python anterior a 2.2: P – wescpy

Respuesta

25

Probar:

lines = iter(open('something.txt', 'r')) 
for val in lines: 
    if val == "!": 
     lines.next() 
     continue 
    <etc> 

es posible que desee ponerse StopIteration en alguna parte. Ocurrirá si el iterador ha terminado.

+5

Puede usar 'next (lines, None)' para suprimir la excepción 'StopIteration'. (Requiere Python 2.6) – interjay

+0

¿hay alguna posibilidad de iteración bidireccional? – UberJumper

+1

No con iteradores predeterminados. Sin embargo, puede crear sus propias clases de estilo de iterador anulando las funciones correctas. – ebo

1

No muy compacta:

skip = False 
for line in open('something.txt'): 
    if skip: 
    skip = False 
    continue 

    if line.strip() == '!': 
    skip = True 
    continue 
+0

línea nunca será igual a ''!'' A menos que primero se eliminen los caracteres de nueva línea del extremo. – tgray

+0

Solucionado al agregar .strip() – Harriv

0

usted podría utilizar la recursividad

input = iter(open('something.txt')) 
def myFunc(item): 
    val = iter.next() 
    if(val == '!'): 
     item.next() 
     return myFunc(item) 
    #continue on with looping logic 

Editted mensaje contenía los siguientes elementos que en realidad no responde a su pregunta:

Ha intentado

[line for line in open('something.txt') if line != '!'] 

para producir una nueva lista? O mejor aún

filter(lambda line: line != '!', open('something.txt')) 
+0

¿Por qué no usar una expresión de generador en lugar de una lista de comprensión?Simplemente reemplace '(' y ']' con '(' y ')' y seguirá siendo iterable, pero no duplicará la lista, importante si el archivo es enorme. –

+1

La versión de recursión se dividirá en archivos con más de 1000 líneas (dependiendo de la implementación de Python). – ebo

+1

A menos que se use el mal trampolín: http://aspn.activestate.com/ASPN/Mail/Message/python-tutor/2302231 –

5

El método file.readlines devuelve una lista de cadenas e iterar sobre una lista no le permitirá modificar la iteración en el cuerpo del bucle. Sin embargo, si se llama a iter en la lista primero por lo que recibirá un iterador que se puede modificar en el cuerpo del bucle:

lines = open('something.txt', 'r').readlines() 
line_iter = iter(lines) 
for line in line_iter: 
    if line == '!': 
     # force iteration forward twice 
     line_iter.next() 
     line_iter.next() 
    <etc> 

Como ebo señala el objeto de archivo en sí actúa como un repetidor, para que pueda obtener el mismo efecto al no llamar líneas de lectura y omitir la llamada a iter.

9

Este es corta, Pythonic, y trabaja:

with open('something.txt', 'r') as f: # or simply f = open('something.txt', 'r') 
    nobang = (line for line in f if line != '!\n') 
    for line in nobang: 
     #... 

Editar:

Como muchos observaron, sin embargo, esto no es la solución. Lo mejor que puedo pensar es una combinación de lo que ya está en esta página:

with open('something.txt', 'r') as f: 
    for line in f: 
     if line == '!\n': 
      next(f,None) # consume next line 
      continue # skip this line 
     # ... 
+0

esto es sintaxis p3k, ¿verdad? – Dingle

+3

Esto no omite la siguiente línea. – interjay

+0

@Dingle: No, solo 2.6 o posterior. –

Cuestiones relacionadas