¿Por qué no puedo iterar dos veces sobre los mismos datos?

Honestamente, estoy un poco confundido aquí, ¿por qué no puedo repetir dos veces sobre los mismos datos?

def _view(self,dbName): db = self.dictDatabases[dbName] data = db[3] for row in data: print("doing this one time") for row in data: print("doing this two times") 

Esto imprimirá “haciendo esto una vez” unas cuantas veces (ya que los datos tienen algunas filas), sin embargo, NO imprimirá “haciendo esto dos veces” en absoluto …

La primera vez que itero sobre los datos funciona bien, pero la segunda vez que ejecuto la última lista “para la fila en los datos”, esto no devuelve nada … así que ejecutarlo una vez funciona pero no dos veces …

FYI – data es un objeto csv.reader (en caso de que sea la razón) …

Es porque los data son un iterador, y puede consumir un iterador solo una vez. Por ejemplo:

 lst = [1, 2, 3] it = iter(lst) next(it) => 1 next(it) => 2 next(it) => 3 next(it) => StopIteration 

Si estamos atravesando algunos datos utilizando un bucle for , esa última StopIteration hará que salga la primera vez. Si intentamos repetirlo nuevamente , seguiremos obteniendo la excepción StopIteration , porque el iterador ya se ha consumido.

Ahora para la segunda pregunta: ¿Qué pasa si necesitamos atravesar el iterador más de una vez? Una solución simple sería crear una lista con los elementos, y podemos recorrerla tantas veces como sea necesario. Esto está bien siempre que haya pocos elementos en la lista:

 data = list(db[3]) 

Pero si hay muchos elementos, es una mejor idea crear iteradores independientes usando tee() :

 import itertools it1, it2 = itertools.tee(db[3], n=2) # create as many as needed 

Ahora podemos pasar por encima de cada uno a su vez:

 for e in it1: print("doing this one time") for e in it2: print("doing this two times") 

Una vez que un iterador se agota, no cederá más.

 >>> it = iter([3, 1, 2]) >>> for x in it: print(x) ... 3 1 2 >>> for x in it: print(x) ... >>> 

Quiero completar la respuesta de @ ÓscarLópez para aquellos que buscan una solución en 2017 y usan Python 2.7 o 3.

El método tee () no toma argumentos de palabras clave ahora y espera a que el segundo argumento sea un entero, no una palabra clave. Esta es la forma correcta de usar tee ():

 import itertools it1, it2 = itertools.tee(db[3], 2)