# Field calculate sequential values, but assign same number to duplicates

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.

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.

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 `LandOwner`s 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 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. Feb 12, 2020 at 20:25