I work at a company where I have to constantly update parcel maps and generate tables representing landowner parcels. I have figured out how to sort the landowner name field in the table alphabetically, then generate sequential numbers for map values, but I'd like to have the landowner ID remain the same number if it's the same landowner. This picture shows what I mean.

enter image description here

I have a basic knowledge of model builder and while I don't know python well, I know how to copy and paste code into the field calculator.

1 Answer 1


You will need to turn on the "Show Codeblock" checkbox in the Field Calculator in order to set some global variables that can be shared across all iterations of the calculation (ie, for all records) and so that you can define a function to perform the calculations which can access these global variables.

This allows the field calculator to maintain some data about previous calculations which can be used in subsequent calculations.

I have just tested the following and it worked OK for me:

Pre-Logic Script Code:

owners = {}
nextID = 1

def getID(name):
    global owners
    global nextID
    if name not in owners:
        owners[name] = nextID
        nextID += 1
    return owners[name]

Expression (Map_ID = ):

getID( !LandOwner! )

How it Works:

owners is a dictionary which stores an ID for each unique LandOwner. nextID is an integer that stores the lowest positive integer that has NOT already been used as an ID for a LandOwner (starting with 1).

The function getID makes these two global variables available within its scope, and gets passed in the name of the LandOwner for this this current calculation is being run.

If the name does not already have an ID assigned to it in the owners dictionary, it assigns the next available ID to it, ie nextID, AND increments nextID to the next lowest unused integer.

Then it simply returns the ID number assigned to the passed in LandOwner's name.

The expression simply calls the getID() function, passing it the value of the LandOwner name for the current record being calculated. This is received by the function in it's name parameter.

NB: There is no need to sort the records. This works whether the LandOwners are sorted or not. In fact, I'm not sure if the field calculator pays any attention to the sort order.

  • This is incredible - Just tried it out and it worked! Thank you so very much for your help! Now the next challenge would be to do this and have the map ID's generate sequentially from north to south... Any idea how to code for that? Thanks again. Very much appreciated
    – Joe G.
    Commented Feb 12, 2020 at 14:33
  • Glad to hear it worked. Your next challenge is doable. Please post it as a new question if you haven’t already. Commented Feb 12, 2020 at 20:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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