Molem7b5
Molem7b5

Reputation: 91

Nested for loop only runs on first iteration

I'm using a list and checking this against information held in a csv file. I'm trying to do it one list item at a time, however after the initial iteration the nested for loop doesn't seem to run.

I've used the initial For loop so the entire loop will run the number of iterations equal to the number of items in the list. The inner for loop then runs for the number of rows in the csv file. The very inner If statements then does stuff if the list item matches the information in the CSV row.

with open('MY_PATH', encoding="utf8") as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',') 
    line_count = 2
    for i in range(0, len(class_numbers)):
        for row in csv_reader:
            if obj_list[i]['name'] in row[1]:
                audiofile = '{}.mp3' .format(row[0][0:8])
                #audio = fetch_file(audiofile)
                print(row[1],'-' , audiofile)
                line_count += 1
            else:
                line_count += 1
                #print('error')

Upvotes: 2

Views: 1952

Answers (2)

Rory Daulton
Rory Daulton

Reputation: 22534

Your csv_reader is an iterable but not a sequence. That means that, once it is created, it can be iterated over (as in your for loop) only once. After that, it is exhausted, and any further attempts to iterate over it will see it as empty. It stays empty until it is destroyed and re-created.

There are several things you could do. You could re-create csv_reader on every loop. Or you could store the contents of that file into a sequence, such as a list--you could use readlines, for example. Or you could swap your two loops--loop over csv_reader first, then inside that, loop over range(0, len(class_numbers)). Or you could reset the reader by csv_file.seek() (thanks to @Barmar for that option.) Each approach has its disadvantages.

Upvotes: 2

azundo
azundo

Reputation: 6052

csv.reader objects can only be iterated over one time, then the iterator is exhausted and it does not have a concept of "resetting" back to the beginning of the csv.

Mostly likely what you want to do is turn the csv into a list first so you can iterate over it multiple times:

with open('MY_PATH', encoding="utf8") as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    # turn csv_reader into a list of rows instead of a reader object
    cvs_rows = list(csv_reader) 
    line_count = 2
    for i in range(0, len(class_numbers)):
        # you can now iterate over the rows as many times as you like
        for row in csv_rows:
            if obj_list[i]['name'] in row[1]:
                audiofile = '{}.mp3' .format(row[0][0:8])
                #audio = fetch_file(audiofile)
                print(row[1],'-' , audiofile)
                line_count += 1
            else:
                line_count += 1
                #print('error')

Upvotes: 0

Related Questions