Search and Update Cursor Need help.

1081
10
Jump to solution
12-09-2013 06:21 AM
HectorChapa
Occasional Contributor II
I am trying to update a shapefile by using search and update cursor.
It searchs great on of the shapefile but when I try to update the other it only retrieves the first data.
I am providing my code so anyone could tell me how to modify it.


import arcpy  fc = "C:/Users/hchapa.LRGVDC911.000/Documents/ArcGIS/Default.gdb/Test_Shapefile_SpatialJoin" field = "parcel_1"   fc2 = "C:/GIS_DATA/Test_Shapefile.shp"   field2 = "parcel" value = [] cursor = arcpy.SearchCursor(fc) UpdateCursor = arcpy.UpdateCursor(fc2)    for row in cursor:     value = row.getValue(field)     for row2 in UpdateCursor:         row2.setValue(field2, value)         UpdateCursor.updateRow(row2)        print "Done"




the problem it only gets the first number but it doesnt iterate to the second number.

What am I doing wrong.

P.S I already try many other solutions nothing works.

I tried using a list.
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
JoshuaChisholm
Occasional Contributor III
I think you have your 'for' loops a little scrambled.

For each row in the search cursor, you're writing to every row in the update cursor. It probably accepts all the data once, which is why you're only getting the first data (over and over again I suspect).

There are many good ways to traverse both lists at the same time, but a simple solution might be to just use a temporary list. Here's what I would try:
import arcpy  fc = "C:/Users/hchapa.LRGVDC911.000/Documents/ArcGIS/Default.gdb/Test_Shapefile_SpatialJoin" field = "parcel_1"  fc2 = "C:/GIS_DATA/Test_Shapefile.shp" field2 = "parcel"  value = [] #You should remove this line. It's not needed.  cursor = arcpy.SearchCursor(fc) UpdateCursor = arcpy.UpdateCursor(fc2)  tempRows = []  for row in cursor:     value = row.getValue(field)     tempRows.append(value)  c = 0 #use as a counter  for row2 in UpdateCursor:     value = tempRows #assumes both this are in the exact same order     row2.setValue(field2, value)     UpdateCursor.updateRow(row2)     c+=1 #count up by 1      del TempRows  print "Done"


This solution assumes both list contain the same number of records in the same order. If this is not the case you will need a way or relating the records between the two table (a Join may work well in that case).

Good luck, let us know how it goes!
~Josh

View solution in original post

0 Kudos
10 Replies
JoshuaChisholm
Occasional Contributor III
I think you have your 'for' loops a little scrambled.

For each row in the search cursor, you're writing to every row in the update cursor. It probably accepts all the data once, which is why you're only getting the first data (over and over again I suspect).

There are many good ways to traverse both lists at the same time, but a simple solution might be to just use a temporary list. Here's what I would try:
import arcpy  fc = "C:/Users/hchapa.LRGVDC911.000/Documents/ArcGIS/Default.gdb/Test_Shapefile_SpatialJoin" field = "parcel_1"  fc2 = "C:/GIS_DATA/Test_Shapefile.shp" field2 = "parcel"  value = [] #You should remove this line. It's not needed.  cursor = arcpy.SearchCursor(fc) UpdateCursor = arcpy.UpdateCursor(fc2)  tempRows = []  for row in cursor:     value = row.getValue(field)     tempRows.append(value)  c = 0 #use as a counter  for row2 in UpdateCursor:     value = tempRows #assumes both this are in the exact same order     row2.setValue(field2, value)     UpdateCursor.updateRow(row2)     c+=1 #count up by 1      del TempRows  print "Done"


This solution assumes both list contain the same number of records in the same order. If this is not the case you will need a way or relating the records between the two table (a Join may work well in that case).

Good luck, let us know how it goes!
~Josh
0 Kudos
HectorChapa
Occasional Contributor II
Josh this works excellent. Thanks, for that list idea. I had the idea using the list but I could count up I was getting confused. but it work.
I am going to use spatial join to join them together but there is catch it creates an output. The target shapefile or feature class can not be rename or change in any particular way because there is another script creating an unique value into that feature class if we change that then we corrupt the algorithm. Basically in the end it gets replicated. Could the script you gave me work in an sde geodatabase.
if so, how would i change my variables fc.

would it have the string saying "Database connection/sde.default"
like that.
0 Kudos
T__WayneWhitley
Frequent Contributor
Just to add to what Josh did, you don't need the list, or furthermore you don't have to wait for the cursor to finish reading into memory the values from your search cursor in order to write to your update cursor.

You could 'dynamically' read/write via incrementing both cursors via the 'next' command as so:
import arcpy

fc = "C:/Users/hchapa.LRGVDC911.000/Documents/ArcGIS/Default.gdb/Test_Shapefile_SpatialJoin"
field = "parcel_1"

fc2 = "C:/GIS_DATA/Test_Shapefile.shp"
field2 = "parcel"

value = [] #You should remove this line. It's not needed.

cursor = arcpy.SearchCursor(fc)
UpdateCursor = arcpy.UpdateCursor(fc2)

# fetch the 1st row, for both search/update cursors
row = cursor.next()
row2 = UpdateCursor.next()

while row:
    row2.setValue(field2, row.getValue(field))
    UpdateCursor.updateRow(row2)
    # advance both cursors to next row obj
    row = cursor.next()
    row2 = UpdateCursor.next()
    
    
del cursor, UpdateCursor

print "Done"


...even further optimized, use the da module ('data access' module) cursors, available with 10.1 and later - see this doc (and the 'next' command is available with da as well):

Accessing data using cursors
Desktop » Geoprocessing » Python » Accessing geographic data in Python
http://resources.arcgis.com/en/help/main/10.2/index.html#//002z0000001q000000
HectorChapa
Occasional Contributor II
whats the difference using the arcpy.UpdateCursor and arcpy.da.UpdateCursor. One is alot faster than the other one. Whats the difference.
0 Kudos
T__WayneWhitley
Frequent Contributor
Good question actually.  You really won't find the answer here (the webhelp link provided just below), although this tells you more about what the module can do for you:

What is the data access module? (arcpy.da)
Desktop » Geoprocessing » ArcPy
http://resources.arcgis.com/en/help/main/10.2/index.html#//018w00000008000000

...or this developer summit presentation introducing the module, an interesting discussion I stumbled across:
http://proceedings.esri.com/library/userconf/devsummit12/papers/introducing_the_arcpy_data_access_mo...


More to the point, Jason Scheirer (ESRI) partly addresses your question:
http://forums.arcgis.com/threads/37439-OH-MY-GOODNESS-CURSORS-ARE-FAAAASSSSTTTT!!#10


If you're still interested, see this thread too:
http://forums.arcgis.com/threads/93195-performance-of-SearchCursor-and-da.SearchCursor


-Wayne
0 Kudos
HectorChapa
Occasional Contributor II
Hey Wayne how would you change the code above to work with the arcpy.da. I am trying just to change it but it complaints.
0 Kudos
T__WayneWhitley
Frequent Contributor
It really isn't difficult - so I take it you did not read any of the webhelp for the da search/update cursor syntax?

Go ahead and award post #2 the answer - the 'big green checkmark' - since he answered your original question and if you're still having difficulty, we'll go from there.
0 Kudos
HectorChapa
Occasional Contributor II
Thanks wayne I figured it out.
0 Kudos
HectorChapa
Occasional Contributor II
I think you have your 'for' loops a little scrambled.

For each row in the search cursor, you're writing to every row in the update cursor. It probably accepts all the data once, which is why you're only getting the first data (over and over again I suspect).

There are many good ways to traverse both lists at the same time, but a simple solution might be to just use a temporary list. Here's what I would try:
import arcpy

fc = "C:/Users/hchapa.LRGVDC911.000/Documents/ArcGIS/Default.gdb/Test_Shapefile_SpatialJoin"
field = "parcel_1"

fc2 = "C:/GIS_DATA/Test_Shapefile.shp"
field2 = "parcel"

value = [] #You should remove this line. It's not needed.

cursor = arcpy.SearchCursor(fc)
UpdateCursor = arcpy.UpdateCursor(fc2)

tempRows = []

for row in cursor:
    value = row.getValue(field)
    tempRows.append(value)

c = 0 #use as a counter

for row2 in UpdateCursor:
    value = tempRows #assumes both this are in the exact same order
    row2.setValue(field2, value)
    UpdateCursor.updateRow(row2)
    c+=1 #count up by 1
    
del TempRows

print "Done"


This solution assumes both list contain the same number of records in the same order. If this is not the case you will need a way or relating the records between the two table (a Join may work well in that case).

Good luck, let us know how it goes!
~Josh


Hey josh what about if I want to get the geometry to make sure they are overlaying each other.
0 Kudos