How to use update cursor with a dictionary?

2770
7
03-07-2019 12:26 PM
RyanHowell1
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

0 Kudos
7 Replies
DanPatterson_Retired
MVP Emeritus

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

0 Kudos
RyanHowell1
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.

DanPatterson_Retired
MVP Emeritus

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'}
‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
JoshuaBixby
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.

RandyBurton
MVP Alum

Try:

row[1] = assignName[row[0]] # to access dictionary, use square brackets not ()
JoshuaBixby
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'
>>> 
0 Kudos
DanPatterson_Retired
MVP Emeritus

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

0 Kudos