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

Ricardo Cárdenes ricardo.cardenes en gmail.com
Dom Jul 12 06:56:34 EDT 2020


>
> Alexis, si, podía ser. Veo un poco más limpia la de Ricardo.


Ojo, más limpio aún sería algo del tipo...

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

    print("Leyendo fondo: ")
    with open('movimientos.csv') as mov_file:
    for fondo in fondos_csv:
        with open('movimientos.csv') as mov_file:
            for movimiento in csv.reader(mov_file, delimiter=';'):
                print("dentro de movimiento")

        print("For exterior")


Es decir, nada de reutilizar el fichero. Claro que eso depende de muchas
cosas. Por ejemplo, de la cantidad de fondos y del coste de abrir el
fichero de nuevo. Pero eso son preocupaciones excesivas, optimización
prematura.

En cualquier caso:

1º: ¿como las cargo en memória? No encuentro documentación.


Tan simple como:

movimientos = list(csv.reader(open('movimientos.csv', delimiter=';')))
# ...

    for movimiento in movimientos:
        # ...

Puedes complicar un poco más la lectura inicial, claro, por ejemplo
convirtiendo cada fila del CSV a una `namedtuple` o `dataclass` con los
valores ya limpios y convertidos a su tipo correspondiente (si fuera
necesario), que además es una optimización interesante porque es algo que
harás una sola vez en lugar de "n" (siendo "n" el número de fondos).

2º ahora es una mierdecilla de uno 120 registros. Pero con el paso del
> tiempo, cuando sea rico, a lo mejor son varios miles :-)) ojalá. ¿a partir
> de que punto crees que merece la pena el cambio entre memoria/disco?
> Supongo que dependerá del equipo donde corra la app


Depende todo de la memoria que tengas :-) Mientras quepa la
lista/tupla/loquesea...

Saludos,
Ricardo

On Sun, Jul 12, 2020 at 12:44 AM Javier Perez <javierperez en perasalvino.es>
wrote:

> Muchas gracias a los tres. Ayer se me complico el día y hasta ahora no lo
> he podio probar.
>
> Alejandro lo de sacarlo a una función no funciono.
>
> Alexis, si, podía ser. Veo un poco más limpia la de Ricardo.
>
> Ricardo, funciona perfectamente.
>
> Pero cuando dices:
>
> 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.
>
>
> 1º: ¿como las cargo en memória? No encuentro documentación.
>
> 2º ahora es una mierdecilla de uno 120 registros. Pero con el paso del
> tiempo, cuando sea rico, a lo mejor son varios miles :-)) ojalá. ¿a partir
> de que punto crees que merece la pena el cambio entre memoria/disco?
> Supongo que dependerá del equipo donde corra la app.
>
> Como se trata de aprender voy a ver si soy capaz de implementar las dos
> opciones y ver el tiempo que tarda en cada una.
>
>
>
> Lo dicho, muchísimas gracias a los tres. Y feliz verano a todos.
>
>
>
>
> Saludos,
>
> --
> Javier Pérez
> http://es.linkedin.com/in/javierperez1
> http://www.perasalvino.es/
>
>
>
>
> El 11 jul 2020, a las 23:44, Ricardo Cárdenes <ricardo.cardenes en gmail.com>
> escribió:
>
> 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
>>
> _______________________________________________
> 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/20200712/b2b4964d/attachment.html>


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