[GIS] arcpy Problem with updateRow() when trying to update fields with UpdateCursor

arcgis-10.0arcpy

I have a list of values which I am trying to add to an existing shapefile. The field where the values need to be inserted has been added via arcpy.AddField_management and thus the values of the rows are empty or 0. The variable expression1 is a list of floats with the length of the rows in the shapefile. To update the rows I use UpdateCursor:

import arcpy
import math
from arcpy import env
env.workspace = "S:/Black grouse modelling/shapefiles"
inFishnet = "fishnet_label.shp"
rows = arcpy.UpdateCursor(inFishnet)
fields = arcpy.ListFields(inFishnet)
for row, i in zip(rows, expression1):
    for field in fields:
        if field.name == "dist":
            print i
            row.setValue(field.name, i)
            rows.updateRow(row)
del rows
del row

The output I get is as follows:

1265.60109093

Traceback (most recent call last):
  File "<pyshell#218>", line 6, in <module>
    rows.updateRow(row)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\arcobjects.py", line 102, in updateRow
    return convertArcObjectToPythonObject(self._arc_object.UpdateRow(*gp_fixargs(args)))
RuntimeError: ERROR 999999: Error executing function.

The value I want it to update with gets printed as requested (1265.60109093). And I think there isn't a problem with the row.setValue() line. The error comes when I am trying to update the row. I have thought it might be an issue with the float numbers. As these might be longer than the field allows for. However, I have tried rounding the numbers and then inputting those values into the rows but that doesn't work either. I have also tried the following code without setValue() but this doesn't work either:

for row, i in zip(rows, expression1):
    print i
    row.dist = i
    rows.updateRow(row)

Any help is appreciated.

EDIT:

as requested the values of expression1:

expression1[:5]
[1265.6010909259928, 1247.9398102685327, 1232.0557693355686, 1218.0185004559901, 1205.8924977596705]

which is calculated via the following function:

def distFrom(self, other):
        ox = other.x
        oy = other.y
        xDist = self.x - ox
        yDist = self.y - oy
        return (xDist**2 + yDist**2)**0.5

Obviously I do not need these values to be so accurate, but rounding them to 2 decimals for example does not solve the problem.

I have also tried it with a different variable where the values are either True or False and converting these to strings. This does also not solve the problem.

I am using python 2.6.5 and arcGIS 10.0

Best Answer

Based on the comments, I think there are two places where you are having a problem.

  1. Since you were able to get the updateRows() function to work when just updating to a simple number, I think your iteration may be a problem. It is possible that ArcGIS doesn't like to step through a cursor that is zipped with something else. I cannot verify this, but if it is possible to avoid, then let's do so.
  2. In your script, there is no place where you actually define expression1. This wasn't defined until I asked, and you pasted it into your answer. If you are simply leaving out part of the script, that is one thing, but if not, then your problem is the variable is empty so the zip operation is creating a list of tuples that are missing one of their components.

Try this code. What I did was instead of zipping together the row cursor and the expression list, I am starting a counter at 0, which will return the first value. Then, as you iterate through the rows, I am adding to the counter, which will return the next value in the list, and so on.

Again, and to be clear, this script is Missing the Definition for expression1

import arcpy
import math
from arcpy import env
env.workspace = "S:/Black grouse modelling/shapefiles"
inFishnet = "fishnet_label.shp"

rows = arcpy.UpdateCursor(inFishnet)

fields = arcpy.ListFields(inFishnet)

stepcount = 0

expression1 = Add Appropriate Definition

for row in rows:
    for field in fields:
        if field.name == "dist":
            expval = expression1[stepcount]

            row.setValue(field.name, expval)
            rows.updateRow(row)

            stepcount += 1
del rows
del row

Edit - Here is a new code block that may work a bit quicker - HT to @David for the push

This moves the field verification block out of the loop. You only need to verify that the field exists one time. If it exists, then cycle through the cursor to update the field.

import arcpy
import math
from arcpy import env
env.workspace = "S:/Black grouse modelling/shapefiles"
inFishnet = "fishnet_label.shp"

fields = arcpy.ListFields(inFishnet)

distvalid = 0

for field in fields:
    if field.name == "dist":
        distvalid = 1

rows = arcpy.UpdateCursor(inFishnet)

expression1 = Add Appropriate Definition

stepcount = 0

if distvalid==1:
    for row in rows:
        expval = expression1[stepcount]    
        row.dist = expval
        rows.updateRow(row)
        stepcount += 1
else:
    print "'dist' field does not exist"
del rows
del row
Related Question