Peter Chappy
Peter Chappy

Reputation: 1179

Nested DictReaders not resetting

I have nested DictReader iterators, but I noticed that for build in building does not reset after each iteration in for row in location causing it to only compare the it to the last object in building after the first iteration. Why is it not resetting?

import csv

building = csv.DictReader(open('tblBuilding.csv', newline=''), delimiter=',', quotechar='"')
purpose = csv.DictReader(open('tblPurpose.csv', newline=''), delimiter=',', quotechar='"')
room = csv.DictReader(open('tblRoom.csv', newline=''), delimiter=',', quotechar='"')
location = csv.DictReader(open('Locations.csv', newline=''), delimiter=',', quotechar='"')

data, i = {}, 0

for row in location:
    result = {}
    for build in building:
        if row['Build'] == build['BuildingName']:
            result['BuildingID'] = build['BuildingID']

Upvotes: 1

Views: 298

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1123830

They don't reset because the underlying file object doesn't reset. You can rewind the file to the start again, but take into account that the first row is then the header row, so skip that too:

building_file = open('tblBuilding.csv', newline='')
building = csv.DictReader(building_file, delimiter=',', quotechar='"')


for row in location:
    result = {}
    for build in building:
        if row['Build'] == build['BuildingName']:
            result['BuildingID'] = build['BuildingID']
    building_file.seek(0)  # rewind the underlying file object to the start again
    next(building)  # skip header row

However, you should not be looping over nested CSV files in the first place. Store the building information in a dictionary before processing locations:

with open('tblBuilding.csv', newline='') as building_file:
    building = csv.DictReader(building_file, delimiter=',', quotechar='"')
    buildings = {b['BuildingName']: b['BuildingID'] for b in building}

The buildings dictionary now maps BuildingName to BuildingID values. Now you can look up buildings in O(1) constant time instead of having to loop over all CSV rows for every location:

for row in location:
    result = {}
    building_id = buildings.get(row['Build'])
    if building_id:
        result['BuildingID'] = building_id

Upvotes: 2

Related Questions