Iterate repeatedly on file parsed using csv.reader

2

I am trying to do a search filter of a tsv file, where the user enters the filters to visualize the data he wants to iterate over the file. The code that I am using is the following:

import csv

with open("results.tsv") as tsvF:
    reader = csv.reader(tsvF, delimiter='\t')
    encabezado = next(reader)
    print(encabezado)

    for indice, col_enc in enumerate(encabezado):
        print(indice, col_enc)


    yearini = input("Desde el año: ")


    years, magnitudes, locations = [],[],[]
    for col in reader:
        year = col[2]
        if year > yearini:
            years.append(year)
            magnitud = float(col[9])
            magnitudes.append(magnitud)
            location = col[19]
            locations.append(location)

    for ind in range(0, len(years)):
       print(years[ind], ":", magnitudes[ind], '-', locations[ind])

    magini = input("Desde :")


    years, magnitudes, locations = [],[],[]
    for col in reader:
       magnitud = col[9]
       if magini > magnitud:
           magnitudes.append(magnitud)
           year = float(col[2])
           years.append(year)
           loation = col[19]
           locations.append(location)

    for ind in range(0, len(years)):
        print(magnitudes[ind], ":", years[ind], '-', locations[ind])

With this code, the first print(years[ind], ":", magnitudes[ind], '-', locations[ind]) if it works but in the same print of the last cycle does not show me the data as it does the first.

    
asked by Diego Sanchez 04.04.2018 в 19:37
source

1 answer

0

reader is an iterator , which means that when you do:

for col in reader:

consume all the items in it (file rows) , so when you try to iterate over it again, with the second for col in reader , you iterate over an empty iterable, so logically the filtering does not take place and the last for does not print anything because years , magnitudes and locations are empty lists.

If you can not group the code in a single iteration on the file, you can do it again by placing the cursor at the beginning of the file again:

import csv

with open("results.tsv") as tsvF:
    reader = csv.reader(tsvF, delimiter='\t')
    encabezado = next(reader)

    for col in reader:
        pass

    tsvF.seek(0)  # Volvemos a colocar el cursor al inicio del fichero
    next(reader)  # Volvemos a consumir el encabezado

    for col in reader:
        pass

Another option depending on the size of your file would be to store the entire contents of the file in memory, in a list for example, and iterate over it as many times as you want:

import csv

with open("a.csv") as tsvF:
    reader = csv.reader(tsvF, delimiter='\t')

    encabezado = next(reader)   # Primera fila, encabezado
    filas = list(reader)        # Resto de filas

    # Sobre la lista puedes iterar cuantas veces quieras

    for fila in filas:
        pass

    for fila in filas:
        pass

If all you want is to print the data the logical thing would be not to create the three lists, but simply to print on the own for in charge of iterating over the rows. If you need lists for something else, then it is more efficient and more readable (in my opinion) using zip :

for year, mag, loc in zip(years, magnitudes, locations):
    print("{} : {} - {}".format(year, mag, loc))

Or if you use Python> = 3.6 use formatted string literals:

for year, mag, loc in zip(years, magnitudes, locations):
    print(f"{year} : {mag} - {loc}")
    
answered by 04.04.2018 в 20:05