Honestamente estoy un poco confundido aquí, ¿por qué no puedo repetir más de dos veces 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")

Se imprimirá «haciendo esto de una vez» un par de veces (como datos tiene un par de filas), sin embargo NO imprimir «hacer esto dos veces» en todos los …

La primera vez que me iterar a través de datos funciona bien, pero la segunda vez, cuando ejecuto el último de la lista «para la fila de datos» este no devuelve nada … así que ejecutarlo una vez funciona, pero no dos veces … ?

FYI – datos de un archivo csv.lector de objeto (en el caso de que esa es la razón)…

  • Iterable vs iterador.
  • No estoy diciendo que este es un duplicado, pero usted puede también querer referirse a stackoverflow.com/questions/9884132/… para más contexto / explicación
  • Siempre puedo contar el fin de semana ha llegado cuando las preguntas básicas, y a menudo su respuesta(s) — llegar tan arriba votado…
  • Por qué no simplemente iterar a través de los datos una vez y hacer todo lo que necesita la primera vez?
  • Relacionados: el Restablecimiento de un objeto iterador
InformationsquelleAutor JSchwartz | 2014-08-16

3 Comentarios

  1. 36

    Es porque data es un iterador, una que puede consumir un iterador sólo 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 for bucle, que el pasado StopIteration haré salir de la primera vez. Si tratamos de iterar sobre ella de nuevo, vamos a seguir recibiendo el StopIteration la excepción, ya que el iterador ya se ha consumido.

    Ahora para la segunda pregunta: ¿y si nos hacer necesidad de atravesar el iterador más de una vez? Una solución sencilla sería la de crear una lista con los elementos, y podemos recorrer tantas veces como sea necesario. Todo esto está bien como hay pocos elementos en la lista:

    data = list(db[3])

    Pero si hay muchos elementos, es una mejor idea para crear independientes iteradores utilizando » t » ():

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

    Ahora podemos recorrer cada uno a su turno:

    for e in it1:
        print("doing this one time")
    
    for e in it2:
        print("doing this two times")
    • it.next() es bueno para este ejemplo como se puede imaginar que el next método está modificando it de alguna manera a mantener un seguimiento de lo que se ha producido (por supuesto, con una gran cantidad de objetos, este «seguimiento» o averiguar el valor siguiente para volver sucede en código C). Sin embargo, en general, cuando la escritura de código, es mejor usar next(it) siempre y cuando usted no necesita apoyo muy viejo versiones de python — Este es compatible con python3.x donde it.next() se cambia el nombre de it.__next__()
    • ok, lo tengo 😉
    • Pero, ¿cómo puedo conseguir alrededor de esto, entonces? Necesito para iterar a través de mi lista varias veces – ¿hay manera de restablecer el iterador al principio (índice 0) o algo así?
    • intente esto: data = list(db[3]). Ahora usted será capaz de recorrer data tantas veces como sea necesario, porque hemos creado una lista con él.
    • Yo realmente no estaba tratando de sugerencia de que debe cambiar la respuesta. Hice una especie de cómo claramente it.next() hace la asociación que it es posible cambiar. next(it) es menos clara, ya que devuelve algo y it se modificó (que no es el más intuitivo cosa en python en general …)
    • Tenga en cuenta que también es posible el uso de itertools.camiseta para duplicar el iterador 😉
    • Esa es una buena sugerencia, he actualizado mi respuesta. Thx!
    • Nota de la documentación en tee: «Este itertool puede requerir mucho de almacenamiento auxiliar (dependiendo de cuánto temporal de las necesidades de datos para ser almacenados). En general, si un iterador utiliza la mayoría o todos los datos antes de que otro iterador se inicia, es más rápido utilizar la lista() en lugar de la conexión en t().» Así que si estás usando it1 y it2 como en el ejemplo, usted podría no estar recibiendo ningún beneficio real de tee (aunque probablemente tomando algunos sobrecarga adicional).

  2. 9

    Una vez un iterador está agotado, no va a rendir más.

    >>> it = iter([3, 1, 2])
    >>> for x in it: print(x)
    ...
    3
    1
    2
    >>> for x in it: print(x)
    ...
    >>>
    • eso tiene sentido, pero ¿cómo puedo conseguir alrededor de él?
    • Convertir el iterador a la secuencia de objeto (list, tuple). Repetir la secuencia de objetos. (Sólo si el tamaño de la csv no es enorme)
    • Alternativamente, si usted puede acceder a los archivos subyacente objeto y que es reubicable. usted puede cambiar la posición del archivo antes de la segunda vuelta: csv_file_object.seek(0)
  3. 2

    Quiero completar la respuesta de @ÓscarLópez para ellos, que busca una solución en el 2017, y se utiliza python 2.7 o 3.

    Método de la conexión en t() no toma argumentos de palabra clave ahora y se espera para el segundo argumento es un entero, no de palabras clave. Esta es la manera correcta de usar la conexión en t():

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

Dejar respuesta

Please enter your comment!
Please enter your name here