4

I want to fill a new field in a shapefile using arcpy. I have differents values so I am using for iterator to run all rows. But when I run the code all rows are filling with the latest row value. The code is:

#-----------------------------
camp= "GROUP"

a= parameters[0].valueAsText

arcpy.AddField_management(a, camp, "TEXT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
#-----------------------------

cursor = arcpy.SearchCursor(a)

for row in cursor:
    n = row.getValue("CODE2012")
    arcpy.CalculateField_management(a, camp, n,"PYTHON_9.3",code_block="")`

I obtain this attribute table:

enter image description here

0

4 Answers 4

6

In your script, calculate field will compute the values of group for ALL the row (or the selected rows if you used a layer) at each iteration. Therefore the GROUP values for all rows are overwritten by has the value of the last "code2012".

Note that you could use "calculate field" only once to update the value of group based on the value of field. For a simple operation this is what I would do.

If you have something more advanced in mind (something that is not possible with the "calculate field") then you should use an "updateCursor" (da)

with arcpy.da.UpdateCursor(fc, ["CODE2012","GROUP"]) as cursor:
    for row in cursor: 
        row[1]=row[0]
        cursor.updateRow(row) 
4

The problem is in arcpy.CalculateField_management. It overwrite ALL of the field rows when you run it. Using selection will solve this problem but it may cause perfomance problems. To avoid them use update cursors.

4

As Mr Che and radouxju have said calculate field does all the rows, and that you should be using an update cursor but I would like to add that you're using an older style of cursor.. the arcpy.da cursors are far superior, here's an example:

#-----------------------------
camp= "GROUP"
a= parameters[0].valueAsText
arcpy.AddField_management(a, camp, "TEXT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
#-----------------------------

with arcpy.da.updateCursor(a, [camp,"CODE2012"]) as UCur:
  for URow in UCur:
    URow[0] = URow[1]
    UCur.updateRow(URow)

In your code you instantiate cursor but don't delete it, this is bad because the lock isn't released on the data in a which causes all sorts of frustration. Using an arcpy.da.updateCursor in a with block (old cursors aren't compatible with with blocks) cleans up the nasty locks... there's a trap for beginners' avoided!

2

If your wanting to simply move one field values into another field the cursor and for loop are not required (but as others noted the newer cursor will provide performance increases especially for larger layers), just point the source field in the CalculateField to !CODE2012!:

arcpy.AddField_management(a, camp, "TEXT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")
#-----------------------------

arcpy.CalculateField_management(a, camp, "!CODE2012!","PYTHON_9.3","")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.