Search code examples
pythondictionarymultidimensional-arrayarcpy

key error when building dict with arrays


I am trying to build two dicts, one with even street values and one with odd street values. Each street has a Ref_ID, and I want each dict to use these values as the keys and their corresponding sequence numbers as the values.

I saw a former post to make a dict with an array as the values: append multiple values for one key in Python dictionary

I tried doing this in my code although I think the conditionals for even and odd as well as using an arcpy.SearchCursor is adding some complexity to the code:

import arcpy

#service location layer
fc = r"J:\Workspace\FAN3 sequencing3\gisdb\layers.gdb\Rts_239_241_314_GoLive"

# create variables

f1 = "Route"
f2 = "Ref_ID"
f3 = "Sequence"
f4 = "Street_Number"

# create containers

rSet = set()
eLinks = dict()
oLinks = dict()

# make a route list

with arcpy.da.SearchCursor(fc, f1) as cursor:
    for row in cursor:
        rSet.add(row[0])
    del row

# list of even side street sequences
eItems = []
eCheckStreet = []

# list of odd side street sequences
oItems = []
oCheckStreet = []

# make two dicts, one with links as keys holding sequence values for the even side of the street
# the other for the odd side of the street

for route in rSet:
    with arcpy.da.SearchCursor(fc, [f2,f3,f4]) as cursor:
        for row in cursor:
            if row[2] != '0' and int(row[2]) % 2 == 0:
                if row[0] in eLinks:
                    eLinks[str(row[0])].append(row[1])
                else:
                    eLinks[str(row[0])] = [row[0]]
            elif row[2] != '0' and int(row[2]) % 2 != 0:
                if row[0] in eLinks:
                    oLinks[str(row[0])].append(row[1])
                else:
                    oLinks[str(row[0])] = [row[0]]
        del row

print eLinks, oLinks

The output is the Ref_ID as both the key and the value. I've tried changing the index just to see if I'd getting soemthing different but it's still the same. I also tried converting if str(row[0]) in eLinks but to no avail.


Solution

  • The issue is likely in the nested if and how those conditions interplay with each other. You don't have to take on your shoulders the responsibility of standard key checks on your dictionary: there's a built-in data structure for your that does that: collections.defaultdict: https://docs.python.org/2/library/collections.html#collections.defaultdict

    import arcpy
    from collections import defaultdict
    
    #service location layer
    fc = r"J:\Workspace\FAN3 sequencing3\gisdb\layers.gdb\Rts_239_241_314_GoLive"
    
    # create variables
    
    f1 = "Route"
    f2 = "Ref_ID"
    f3 = "Sequence"
    f4 = "Street_Number"
    
    # create containers
    
    rSet = set()
    eLinks = defaultdict(list)
    oLinks = defaultdict(list)
    
    # make a route list
    
    with arcpy.da.SearchCursor(fc, f1) as cursor:
        for row in cursor:
            rSet.add(row[0])
        del row
    
    
    # make two dicts, one with links as keys holding sequence values for the even side of the street
    # the other for the odd side of the street
    
    for route in rSet:
        with arcpy.da.SearchCursor(fc, [f2,f3,f4]) as cursor:
            for row in cursor:
                if row[2] != '0' and int(row[2]) % 2 == 0:
                    eLinks[str(row[0])].append(row[1])
                elif row[2] != '0' and int(row[2]) % 2 != 0:
                    oLinks[str(row[0])].append(row[1])
            del row
    print eLinks, oLinks