ArcPy Scripting – How to Calculate SUM of Multiple Fields into New Field

arcmaparcpycursor

I have 4 fields (STREAMS, SLOPE_ASPECT, FIRES, TREES) that are assigned either a 1 or a 0 based on whether they exist or not.

The goal: Create a new field "ranking" the best locations (essentially, where all four = 1)

The assignment says "Create a RANK field and calculate the sum of the 4 fields".
I am currently trying to use a SearchCursor and InsertCursor from another question about something similar but this results in no change and continues displaying "NULL". I am very new to this.

Here's what I've got:

SearchArea = r'C:...'
fc = SearchArea
#Establish local variable for Ranks field
MushroomRanks = "RANKS"
newFields = ['STREAMS', 'SLOPE_ASPECT', 'FIRES', 'TREES', 'RANKS']
#Add RANKS field
arcpy.AddField_management(SearchArea, MushroomRanks, "SHORT")
#Create a variable for our SUM
values = []
#Search cursor to calculate the sum of new fields and store them into a "values" variable
with arcpy.da.SearchCursor(fc, newFields) as Scursor:
    thisValue = 0
    for row in Scursor:
    thisValue += row[0]
    values.append(thisValue)
newFields.append(MushroomRanks)
#Inserts the stored sums
with arcpy.da.InsertCursor(fc, MushroomRanks) as cur:
      cur.insertRow(values)

Best Answer

Your code appears to attempt to copy all the "STREAMS" values (row[0]) to the "RANKS" field and ignores all the other fields (row[1:4]).

But then you use an InsertCursor instead of an UpdateCursor and attempt to append those "STREAM" values as new rows instead of updating the "RANK" field in the existing rows.

You could do this with a simple Calculate Fields expression without any scripting at all, e.g.

sum([!STREAMS!, !SLOPE_ASPECT!, !FIRES!, !TREES!])

Or if if you want to use arcpy:

arcpy.management.CalculateField(
    fc, MushroomRanks, 
    "sum([!STREAMS!, !SLOPE_ASPECT!, !FIRES!, !TREES!])", 
    "PYTHON3")

But if you must use a cursor, use an UpdateCursor not an InsertCursor and there's no need for a SearchCursor at all:

with arcpy.da.UpdateCursor(fc, newFields) as rows:
    for row in rows:
        row[-1] = sum(row[:-1])  # sum all values except the last and assign to the last (row[-1])
        # Does the same as
        # row[4] = sum(row[0:4]) # sum 1st 4 values and assign to the 5th (row[-1])
        rows.updateRow(row)