Update Cursor Dictionary

576
3
04-27-2022 03:29 PM
2Quiker
Occasional Contributor II

I am trying to pass some attributes from my layer to another but I am having an issue is with passing attributes from field 'Field4', the attributes from the layer sjpoints field 'Field4_1' doesn't match so the fc_dest layer 'Field4' and doesn't get updated.

The issue is FIELD4_1 has abbreviations and fc_dest has domains. How can modify my current code to check that field and if it has certain abbreviations to update with certain text, or would it be best to do a separate updatecursor and if so how can I pass the nest dictionary from the spatial join to update the fc_dest layer?

sjpoints - the spatial join has this

TARGET_FIDFIELD4_1

32145

MH

13245

SFR

 

fc_dest - I need this

OIDFIELD4
32145MOBILE HOME
12345

SINGLE FAMILY RES

 

sourceFieldsList = ['TARGET_FID', poly,'Field1_1','Field2_1','Field3_1','Field4_2','Field4_1','Field5_1','Field6_1']

    # define the field list to the original points
    updateFieldsList = ['OID@', Pnt,'Field1','Field2','Field3','Field4','Field5','Field6]
                        
     #Run the Spatial Join tool, using the defaults for the join operation and join type
    arcpy.SpatialJoin_analysis(ptSelection, parcel, sjpoints)

    with arcpy.da.UpdateCursor(fc_dest, updateFieldsList) as updateRows:  
        for updateRow in updateRows:  
            # store the Join value of the row being updated in a keyValue variable  
            keyValue = updateRow[0]  
            # verify that the keyValue is in the Dictionary  
            if keyValue in valueDict:  
                # transfer the values stored under the keyValue from the dictionary to the updated fields.  
                for n in range (1,len(sourceFieldsList)):  
                    updateRow[n] = valueDict[keyValue][n-1]  
                updateRows.updateRow(updateRow) 

 

0 Kudos
3 Replies
BlakeTerhune
MVP Regular Contributor
valueDict is undefined in your code snippet so please update if I'm missing something. If you don't have a coded value domain in the geodatabase for the values in Field4, you'll have to define them in your code. I would suggest a dictionary.

 

field4_coded_values = {
    "MH": "MOBILE HOME",
    "SFR": "SINGLE FAMILY RES",
    # etc...
}

 

Then look up your abbreviation in the dictionary to get the the full value. Passing the look up value (abbreviation) in as the second argument means that is what will be returned if it doesn't exist.

for updateRow in updateRows:
    # Look up full text of abbreviation. Return original value if not found.
    field4 = updateRow[5]
    field4_out_value = field4_coded_values.get(field4, field4)
    updateRow[5] = field4_out_value
0 Kudos
2Quiker
Occasional Contributor II

Thank you and I appreciate the replay.

I guess I am still stuck on if I add this to my current code and if so how or do I completely do a separate updatecursor.

When I posted the ValueDict got cut off.

 

valueDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(sjpoints1, sourceFieldsList)}
    
sourceFieldsList = ['TARGET_FID', poly,'Field1_1','Field2_1','Field3_1','Field4_2','Field4_1','Field5_1','Field6_1']

# define the field list to the original points
updateFieldsList = ['OID@', Pnt,'Field1','Field2','Field3','Field4','Field5','Field6']
                    
 #Run the Spatial Join tool, using the defaults for the join operation and join type
arcpy.SpatialJoin_analysis(ptSelection, parcel, sjpoints)

with arcpy.da.UpdateCursor(ptSelection, updateFieldsList) as updateRows:  
    for updateRow in updateRows:  
        # store the Join value of the row being updated in a keyValue variable  
        keyValue = updateRow[0]  
        # verify that the keyValue is in the Dictionary  
        if keyValue in valueDict:  
            # transfer the values stored under the keyValue from the dictionary to the updated fields.  
            for n in range (1,len(sourceFieldsList)):  
                updateRow[n] = valueDict[keyValue][n-1]  
            updateRows.updateRow(updateRow) 

 

0 Kudos
BlakeTerhune
MVP Regular Contributor

Your logic is difficult to follow, but it looks like you're updating everything based on what is in the valueDict so maybe update the abbreviations there. Please rearrange and adjust as necessary.

sourceFieldsList = ['TARGET_FID', poly,'Field1_1','Field2_1','Field3_1','Field4_2','Field4_1','Field5_1','Field6_1']

# define the field list to the original points
updateFieldsList = ['OID@', Pnt,'Field1','Field2','Field3','Field4','Field5','Field6']

valueDict = {r[0]:(r[1:]) for r in arcpy.da.SearchCursor(sjpoints1, sourceFieldsList)}

# Update abbreviation field values to full text description.
abbreviation_lookup = {
    "MH": "MOBILE HOME",
    "SFR": "SINGLE FAMILY RES",
    # etc...
}
for key, rest_of_the_fields in valueDict.items():
    # Look up full text of abbreviation. Return original value if not found.
    # I don't know which index your abbreviation data is at. Maybe it's rest_of_the_fields[6] ?
    rest_of_the_fields[5] = abbreviation_lookup.get(rest_of_the_fields[5], rest_of_the_fields[5])
    # Update the original values.
    valueDict[key] = rest_of_the_fields

# Run the Spatial Join tool, using the defaults for the join operation and join type
arcpy.SpatialJoin_analysis(ptSelection, parcel, sjpoints)

with arcpy.da.UpdateCursor(ptSelection, updateFieldsList) as updateRows:
    for updateRow in updateRows:
        # store the Join value of the row being updated in a keyValue variable
        keyValue = updateRow[0]
        # verify that the keyValue is in the Dictionary
        if keyValue in valueDict:
            # transfer the values stored under the keyValue from the dictionary to the updated fields.
            for n in range (1,len(sourceFieldsList)):
                updateRow[n] = valueDict[keyValue][n-1]
            updateRows.updateRow(updateRow)