Select to view content in your preferred language

Update Cursor infinite loop

1981
10
Jump to solution
06-29-2012 10:09 AM
SusieGreen
Emerging Contributor
Hello everyone,

I am a python newbie and trying to update a field in a table based on a field in a feature class. The table already contains unique id's that have to match the id's in the feature class.
What happens with the code below is that it goes in an infinite loop where it writes just the first value from the feature class in all the table rows.
Any help would be greatly appreciated.

# write Value to Table         # search cursor         scurs = arcpy.SearchCursor(infc)         # update cursor         ucurs = arcpy.UpdateCursor(tbl)         for scur in scurs:             newRow = scur.getValue("ID")             while newRow <> 0:                 for ucur in ucurs:                     ucur.Value = scur.getValue("Value")                     # update row                     ucurs.updateRow(ucur)
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JakeSkinner
Esri Esteemed Contributor
The problem before was that the dictionary was not sorted correctly.  You can do this one of two ways.

1.  Using an a data dictionary with an updateCursor:
table = "Basins.dbf" fc = "Watersheds.shp"  fcDict = {}  rows = arcpy.SearchCursor(fc, "", "", "", "ID A") for row in rows:     fcDict[row.ID] = row.Value del rows, row  x = 0  rows = arcpy.UpdateCursor(table, "", "", "", "ID A") for row in rows:     if row.ID == sorted(fcDict):         row.Value = fcDict[row.ID]         rows.updateRow(row)         print "Successfully updated row"     x += 1 del rows, row


2.  Create a Join and then calculate values using the Field Calculator:
table = "Basins.dbf" fc = "Watersheds.shp"  arcpy.MakeTableView_management(table, "Basins_view") arcpy.AddJoin_management("Basins_view", "ID", fc, "ID")  arcpy.CalculateField_management("Basins_view", "basins.Value", "[watersheds.Value]")

View solution in original post

0 Kudos
10 Replies
JakeSkinner
Esri Esteemed Contributor
Hi Susie,

Are you trying to update a field within a table with a field within a feature class, where the table and feature class share a common ID?

If that is correct, you could do this using data dictionaries.  The code below is going to update a field called 'Name' within the Airports_Info table from a field also called 'Name' in the Airports feature class.  The unique ID between the two is the field OBJECTID in the feature class, and ID in the table.

table = "Airports_Info"
fc = "Airports"

fcDict = {}

rows = arcpy.SearchCursor(fc, "", "", "", "OBJECTID A")
for row in rows:
    fcDict[row.OBJECTID] = row.Name
del rows, row

x = 0

rows = arcpy.UpdateCursor(table, "", "", "", "ID A")
for row in rows:
    if row.ID == fcDict.keys():
        row.Name = fcDict[row.ID]
        rows.updateRow(row)
        print "Successfully updated row"
    x += 1
del rows, row
0 Kudos
SusieGreen
Emerging Contributor
Hi Jake,
thank you! That is exactly, what I am trying to do. I adjusted the code to fit your example and I get an error on line 11: IndexError: list index out of range.
Here is my code:
        fcDict = {}
        rows = arcpy.SearchCursor(infc,"","","","ID")
        for row in rows:
            fcDict[row.ID] = row.Value
        del rows, row
        
        x = 0
        
        rows = arcpy.UpdateCursor(tbl,"","","","ID")
        for row in rows:
            if row.ID == fcDict.keys():
                row.Value = fcDict[row.ID]
                rows.updateRow(row)
            x += 1
        del rows, row
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Try changing your Search and Update cursors to:

rows = arcpy.SearchCursor(infc,"","","","ID A")

rows = arcpy.UpdateCursor(tbl,"","","","ID A")


The 'A' after ID will sort the fields in Ascending order.  Let me know if you receive the same error.
0 Kudos
SusieGreen
Emerging Contributor
Hi Jake,
unfortunately I receive the same error.
I replaced the x in the following line with the index of the actual length of my list, like this: if row.ID == fcDict.keys()[10]:
That updated my 11 rows just fine. The problem is though that the length of that list varies. Do you know how to fix that.
Thank you,
0 Kudos
JakeSkinner
Esri Esteemed Contributor
Could you send me a subset of the data?  You can send me a private message with zipped attachment by clicking on my user name > Private Message.
0 Kudos
SusieGreen
Emerging Contributor
Hi Jake,
I could not figure out how to add an attachment to a private message.
So here is some sample data.
Thank you 🙂
0 Kudos
JakeSkinner
Esri Esteemed Contributor
The problem before was that the dictionary was not sorted correctly.  You can do this one of two ways.

1.  Using an a data dictionary with an updateCursor:
table = "Basins.dbf" fc = "Watersheds.shp"  fcDict = {}  rows = arcpy.SearchCursor(fc, "", "", "", "ID A") for row in rows:     fcDict[row.ID] = row.Value del rows, row  x = 0  rows = arcpy.UpdateCursor(table, "", "", "", "ID A") for row in rows:     if row.ID == sorted(fcDict):         row.Value = fcDict[row.ID]         rows.updateRow(row)         print "Successfully updated row"     x += 1 del rows, row


2.  Create a Join and then calculate values using the Field Calculator:
table = "Basins.dbf" fc = "Watersheds.shp"  arcpy.MakeTableView_management(table, "Basins_view") arcpy.AddJoin_management("Basins_view", "ID", fc, "ID")  arcpy.CalculateField_management("Basins_view", "basins.Value", "[watersheds.Value]")
0 Kudos
SusieGreen
Emerging Contributor
Thank you, Jake!
Now it works perfectly. Much appreciated 😄
0 Kudos
PapantzinCid
Deactivated User
Hello, I am a python novice and am having similar trouble with data dictionaries and cursors. I have a feature class that I added a new field to (Geology_Class). I want to update the new field with the items from my dictionary. The keys in the dictionary are PTYPE and I want the new field to contain the values. I created a search cursor so that it would loop through the existing PTYPE field (there are about 60 I just provided a snippet) in my feature class. I then added the update cursor so that it would search the PTYPE and add it to the new Geology_Class field. When I run the script I get an error "Traceback (most recent call last):
"File "C:\Users\Users\Desktop\GeoDis.py", line 42, in <module> row[2] = dictionary(row[1]) TypeError: 'dict' object is not callable." or I get "does not support indexing".  Upon reading other forums is looks like I am trying to call a function when in reality it's not? I want to try and avoid pointing to a separate table.
Any help you can offer is greatly appreciated. Thank you.

Using ArcGIS 10.0
# Import arcpy module
import arcpy
from arcpy import env
arcpy.env.overwriteOutput = True

dictionary = {'C':'INSERT1','Ca':'Coarse-Competent','D':'INSERT2' ,'E':'Fine-Competent','Ec':'Coarse-Competent',
'E-Ep':'INSERT3','Ep':'Coarse-Competent','gb':'Crystalline','gr':'INSERT4','grCz':'INSERT5','grCz?':'INSERT6','gr-m':'Crystalline','grMz':'Crystalline', 'grMz?':'Crystalline'}


Input_Geology_Feature_Class = arcpy.GetParameterAsText(0)

searchCursor = arcpy.SearchCursor(Input_Geology_Feature_Class,"","","PTYPE","")



arcpy.AddMessage("Adding Geology Class Field...")
arcpy.AddField_management(Input_Geology_Feature_Class, "Geology_Class","TEXT")



arcpy.AddMessage("Populating Geology Class Field, Please Wait...")
geology = arcpy.UpdateCursor(Input_Geology_Feature_Class,["PTYPE", "Geology_Class"])

for row in geology:
    row[0] = dictionary(row[1])
    geology.updateRow([row])
del row, geology
0 Kudos