1

How do I ensure the script recognizes field values that have already been “used” in a previous row (not necessarily the one just above it)?

Below is my source table – the result of a spatial join between two feature classes (equivalent to a land parcel). I have multiple “allocation claim numbers” (AllocClmNum, 1st field) with their respective “recipient credit values” (RecClmNum, 2nd field) associated to one “recipient claim number (RecClmNum, 3rd field) and its credit value (RecCredValReal, 4th field).

The script I have subtracts funds from the AllocCreVal (allocation credit value stored in a dictionary) from each RecCreClmNum so that the RecCredValReal value becomes zero, and until the AllocCreVal reaches a value at or above 15000 and stores the result in a new table (second one below). In this way the script uses result of the previous the AllocCreVal subtraction and applies it to the next row. The output is shown in the second table : the RecClmNum values to which the script was applied are in the field RecipientClaims. This part works fine (see second table).

source table

The problem is that the script runs regardless of whether the RecClmNum has already been allocated. What I can’t solve is how to NOT include those RecClmNum rows that have already had an allocation applied to them (those highlighted in the green squares). There are about 10000 of these records to go through.

The values in green should not have been calculated since they were already done using the previous AllocClmNum values.

resulting table

# set your variables for the Allocation Claims feature class
updateFC_AllocClms = "SortedAllocationClaims"
fields_AllocClms = ["AllocClmNum","CorrAllocCreVal","RecipientClaims"]

# set your variables for the feature class with the joined Allocation Claims and Recipient Claims (spatial)
sourceFC_AllocClmsSpj = "AllocationClaimsSPJ"
fields_AllocClmsSpj = ["OBJECTID","AllocClmNum","RecClmNum","RecCreVal","AllocStatus"]


# set the dictionary variables
Dict_AllocClmsSpj = {} 

# alternative dictionary with "false" values
# source:  Richard Fairhurst
with arcpy.da.SearchCursor(sourceFC_AllocClmsSpj,fields_AllocClmsSpj) as searchRows: 
    for searchRow in searchRows: 
        keyValue = searchRow[1] 
        if not keyValue in Dict_AllocClmsSpj:
            lstRow = list(searchRow[1:])
            lstRow.append(False) 
            # assign a new keyValue entry to the dictionary storing a list 
            Dict_AllocClmsSpj[keyValue] = [lstRow] 
        else:
            lstRow = list(searchRow[1:])
            lstRow.append(False) 
            # dictionary keyValue exists so append to the list
            Dict_AllocClmsSpj[keyValue].append(lstRow)

# run the script

# update the Sorted Allocation Claims FC with the new values for Allocation Credits ("CorrAllocCreVal") 
with arcpy.da.UpdateCursor(updateFC_AllocClms, fields_AllocClms) as upRows:
    for upRow in upRows:
        x = upRow[2]
        comma = ","
        KeyAllocationClaim = upRow[0] # key value is AllocClmNum
        # KeyRecipientClaims = upRow[2] # value represents the recipient claim numbers
        if KeyAllocationClaim in Dict_AllocClmsSpj: # if the KeyAllocationClaim is in the dictionary
            for record in Dict_AllocClmsSpj[KeyAllocationClaim]:
                # something like: if record[1] not in upRow[2]
                # return the list of values in the field "RecipientCLaims" (upRow[2]).
                    # if record[1] (RecClmNum from 
                if record[4] == False:
                    if (upRow[1] - record[2]) >= 15000: # and as long as credit value is >= to 15000
                        upRow[1] = upRow[1] - record[2] # subtract the Allocation Credit Value from the Recipient Credit Value in the  Dict_AllocClmsSpj
                        # append all the recipient claim numbers "record[1]" to the field "RecipientClaims" in the "SortedAllocationClaims" table separated by a comma 
                        upRow[2] = upRow[2] + record[1] + comma
                        record[4] = True

                        upRows.updateRow(upRow)
  • This is more pure Python than GIS -- A basic application for a set or dictionary. – Vince Sep 16 '16 at 23:12
3

Create a python set and add every value to it when it's used, and then do a check if that value exists in the set before adding it to your row.

Concept something like this (I haven't gone through your script to determine which rows/values/parameters go where as I don't have ArcGIS on this machine to test it out)

Adding value to set once used:

exValue = set()
# add your value to whatever row, then add to set
exValue.add("value")

Using value if not already used:

# Check if value has been used previously, and only use it if it hasn't
if "value" not in exValue:
    # add to your current row

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.