How to use update cursor with a dictionary?

787
7
03-07-2019 12:26 PM
Highlighted
New Contributor III

Newbie here.

I'm self-teaching about cursors and am practicing on this dataset. "testclass" is a feature class with an ID field (6 digit integer) and a name field. I want to go through and assign a unique name based on the ID. The following code works and illustrates more or less what I am trying to do (although I am sure it gives many of you heartburn with how clunky it is-- sorry ).

point = "testclass"
update = arcpy.da.UpdateCursor(point,["ID", "name"])

for row in update:
ID = row[0]
if (ID == '174769'):
name = "R4S8f"
row[1] = name
elif (ID == '174771'):
name = "C3F8m"
row[1] = name
elif (ID == '174773'):
name = "F4S8m"
row[1] = name
elif (ID == '174774'):
name = "C1S8f"
row[1] = name
elif (ID == '174776'):
name = "F3S8f"
row[1] = name
elif (ID == '174778'):
name = "R1S8f"
row[1] = name
elif (ID == '174781'):
name = "R6F8f"
row[1] = name

update.updateRow(row)

I would like to take this same concept and use an update cursor with a dictionary. I've found several posts online so I think I'm close but I can't quite get the syntax. This is what I have.

assignName = {174769 : 'R4S8f', 174771 : 'C3F8m', 174773 : 'F4S8m', 174774 : 'C1S8f',
174776 : 'F3S8f', 174778 : 'R1S8f', 174781 : 'R6F8f'}

cursor = arcpy.da.UpdateCursor('testclass',["ID", "name"])

for row in cursor:
if row.ID in assignName:
updateRow.name = assignName[updateRow.ID]
update.updateRow(row)

It's telling me in line 7 "'list' object has no attribute 'ID'" when I run this in ArcGIS Pro.

Thanks in advance

Reply
0 Kudos
7 Replies
Highlighted
MVP Esteemed Contributor

row has two entries,  ["ID", "name"], you can slice, ie row[0] if you want the ID or row[1] if you want the name

Reply
0 Kudos
Highlighted
New Contributor III

Thanks for your input Dan. I've made those changes (and fixed a couple of other typos from switching around names I found) and now have the following. It runs without an error but doesn't update the table (the ID field is populated but the name is not).

for row in cursor:
if row[0] in assignName:
row[1] = assignName(row[0])
cursor.updateRow(row)

I'm beginning to think I don't understand either dictionaries or update cursors as well as I thought I did.

Highlighted
MVP Esteemed Contributor

I would throw some print statements in.

UpdateCursor—Data Access module | ArcGIS Desktop 

assignName = {174769 : 'R4S8f', 174771 : 'C3F8m', 174773 : 'F4S8m', 174774 : 'C1S8f',
174776 : 'F3S8f', 174778 : 'R1S8f', 174781 : 'R6F8f'}

row0 = 174769

row0 in assignName
True

assignName[row0] = 'hello'

assignName

{174769: 'hello',
174771: 'C3F8m',
174773: 'F4S8m',
174774: 'C1S8f',
174776: 'F3S8f',
174778: 'R1S8f',
174781: 'R6F8f'}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Reply
0 Kudos
Highlighted
MVP Esteemed Contributor

I suspect your conditional check is never coming back True because the following

assignName(row[0])

will generate a TypeError since dictionaries are not callable.

Highlighted
MVP Regular Contributor

Try:

row[1] = assignName[row[0]] # to access dictionary, use square brackets not ()
Highlighted
MVP Esteemed Contributor

As I mentioned back in March, if your code isn't generating any errors, then Line 02 is never evaluating to True because Line 03 will generate a TypeError if it ever gets called.

>>> row = ['foo', 'bar']
>>> assignName = {'foo':'hi', 'bar':'bye'}
>>>
>>> assignName(row[0])
Runtime error
Traceback (most recent call last):
File "<string>", line 1, in <module>
TypeError: 'dict' object is not callable
>>>

Also, as Randy Burton‌ mentioned in March, you look up values in dictionaries by using square brackets and not parentheses:

>>> row = ['foo', 'bar']
>>> assignName = {'foo':'hi', 'bar':'bye'}
>>> assignName('foo')
>>>
>>> assignName[row[0]]
'hi'
>>>
Reply
0 Kudos
Highlighted
MVP Esteemed Contributor

To be overt... see lines 8 and 12 in my example

Reply
0 Kudos