[Python-es] Problemas a la hora de recorrer un CVS

Ricardo Cárdenes ricardo.cardenes en gmail.com
Sab Jul 11 17:44:33 EDT 2020


>
> Puedes consultar la documentación del módulo csv para ver si el reader te
> permite "rebobinar" y así empezar a leer nuevamente desde el principio.


No, los objetos _csv.reader son iteradores puros y duros.

Pero iteran sobre un objeto de tipo fichero, así que hay un truco...

with open('movimientos.csv') as mov_file:
    fondos_csv = csv.reader(open('fondos.csv'), delimiter=';’)

    print("Leyendo fondo: ")
    for fondo in fondos_csv:
        # Volvemos al inicio
        mov_file.seek(0)
        for movimiento in csv.reader(mov_file, delimiter=';'):
            print("dentro de movimiento")

        print("For exterior")

En realidad no hay necesidad de recrear el "reader" para los movimientos
cada vez. Un simple "seek(0)" del fichero basta y funciona bien. Pero queda
más limpio.

Aunque para ser sinceros, si el fichero de movimientos no es muy grande,
simplemente cargaría todas las líneas en memoria y me ahorraría tener que
leerlas cada vez desde disco.

Saludos,
Ricardo

On Sat, Jul 11, 2020 at 2:13 AM Alexis Roda <
alexis.roda.villalonga en gmail.com> wrote:

> Hola,
>
> El problema es que has agotado los elementos y el reader no tiene nada que
> devolver. A efectos prácticos a partir de la segunda vez que ejecutas el
> bucle interno no realiza ninguna iteración.
>
> Puedes consultar la documentación del módulo csv para ver si el reader te
> permite "rebobinar" y así empezar a leer nuevamente desde el principio.
>
> Otras solución, no muy eficiente, sería mover la creación del reader
> dentro del bucle:
>
>
> fondos_csv = csv.reader(open('fondos.csv'), delimiter=';’)
>
> print("Leyendo fondo: ")
> for fondo in fondos_csv:
>     movimientos_csv = csv.reader(open('movimientos.csv'), delimiter=';')
>     for movimiento in movimientos_csv:
>         print("dentro de movimiento")
>
>     print("For exterior")
>
>
> de esta forma en cada iteración del bucle externo se crea un nuevo reader,
> posicionado al principio.
>
> Sin conocer exactamente lo que haces no sé si es factible pero
> personalmente intentaría hacer algo como esto:
>
> movimientos_csv = csv.reader(open('movimientos.csv'), delimiter=';')
>
> movimientos_dict = {}
> for mov in movimientos_csv:
>     if mov.codigo_fondo not in movimientos_dict:
>         movimientos_dict[mov.codigo_fondo] = []
>     movimientos_dict[mov.codigo_fondo].append(mov)
>
> fondos_csv = csv.reader(open('fondos.csv'), delimiter=';’)
> for fondo in fondos_csv:
>
>     for mov in movivientos_dict.get(i.codigo, ()):
>
>         procesar(fondo, mov)
>
>
> Precarga los movimientos y los clasifica por fondo. Solo recorres la lista
> de movimientos una vez (dos en realidad) en lugar de recorrerla entera para
> cada fondo. Carga los movimientos en memoria, puede ser problemático si
> tienes muchos.
>
>
> Espero que te sirva.
>
> Saludos
>
> Missatge de Javier Perez <javierperez en perasalvino.es> del dia ds., 11 de
> jul. 2020 a les 13:31:
>
>> Hola a todos, buenos días,
>>
>>
>> Necesito vuestra ayuda. Llevo una horas y no soy capaz de seguir ni de
>> entender donde esta el problema.
>>
>>
>> Tengo dos CSV que los importo y hasta ese punto sin problemas.
>>
>> Después quiero recorrer uno (“fondos” en mi app). Y para cada linea cada
>> línea de “fondos” tiene que recorrer el otro CSV que llamo “movimientos”.
>> Si coinciden en el código del isbn empieza a hacer una serie de cálculos.
>>
>> Bien, pues solo me recorre una vez “movimientos”, la primera.
>>
>> Os pongo los trozos de código:
>> movimientos_csv = csv.reader(open('movimientos.csv'), delimiter=';')
>>
>> fondos_csv = csv.reader(open('fondos.csv'), delimiter=';’)
>>
>> print("Leyendo fondo: ")
>> for fondo in fondos_csv:
>>     for movimiento in movimientos_csv:
>>         print("dentro de movimiento")
>>
>>     print("For exterior")
>>
>>
>>
>>
>>
>> Y esto sale por el terminal:
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> For exterior
>> For exterior
>> For exterior
>> For exterior
>> For exterior
>> For exterior
>> For exterior
>> For exterior
>> For exterior
>> For exterior
>> For exterior
>>
>> Y entiendo que tenia que salir:
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> For exterior
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> For exterior
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> For exterior
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> dentro de movimiento
>> etc
>>
>>
>>
>> Saludos,
>>
>> --
>> Javier Pérez
>> http://es.linkedin.com/in/javierperez1
>> http://www.perasalvino.es/
>>
>>
>>
>>
>> _______________________________________________
>> Python-es mailing list
>> Python-es en python.org
>> https://mail.python.org/mailman/listinfo/python-es
>>
> _______________________________________________
> Python-es mailing list
> Python-es en python.org
> https://mail.python.org/mailman/listinfo/python-es
>
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://mail.python.org/pipermail/python-es/attachments/20200711/6425cd66/attachment.html>


Más información sobre la lista de distribución Python-es