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
2 Answers 2
Based on the comments, I think there are two places where you are having a problem.
- 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. - 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 thezip
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
-
Just a nitpick, but do you really need to loop through all the fields for each feature? You already know that the field of interest is named "dist". Inner loops like this really slow down the script.David– David2013年05月07日 22:31:42 +00:00Commented May 7, 2013 at 22:31
-
@David - Completely valid point, which was actually bothering me as well. I simply copied the code that was used originally, which to his credit, is a direct copy of a code sample from the ArcGIS help pages. I'm going to add a new code block using the data access module, which should be faster yet.Get Spatial– Get Spatial2013年05月07日 22:43:44 +00:00Commented May 7, 2013 at 22:43
-
@David - Scratch that about the data access module, as that is 10.1 only, but I will revise the code to move the field verification out of the loop.Get Spatial– Get Spatial2013年05月07日 22:56:34 +00:00Commented May 7, 2013 at 22:56
This might sound silly: Rename the folder or move the data to something without spaces in the name.
1
and have it work properly? If it won't even do that, then there is something else going on.