[GIS] Using arcpy.UpdateCursor to delete rows does not delete based on counter

arcgis-10.0arcpycursor

I am trying to delete rows from a shapefile using arcpy.UpdateCursor. The first thing I did was get a unique list of values from the key field "PolyGUID", then I iterate that list doing a arcpy.UpdateCursor. When inside the cursor I set a counter x=0 then for each record I increment +1. The deleteRow doesn't seem to happen after the second record is deleted. Is the object returned by the UpdateCursor not able to operate in this manner? Here's the code..

import arcpy
from arcpy import env

outPointFromPoint = r"C:\Trash\Nov2011\ResFinalC6.shp"
sql = " \"PolyGUID\" <> ''"
ocur = arcpy.SearchCursor(outPointFromPoint, sql)
listDelete = []
for oc in ocur:
    if oc.PolyGUID not in listDelete:
        listDelete.append(oc.PolyGUID)
print len(listDelete)


del oc, ocur, x, sql
for lD in listDelete:
    sql2 = " \"PolyGUID\" = " + "'" + str(lD) + "'"
    upcur = arcpy.UpdateCursor(outPointFromPoint, sql2, "", "", "FMEAS2 A")
    x=0
    for upc in upcur:
        x=x+1
        print upc.FMEAS2
        #print x
        if x==1:
            print x
        else:
            print "--------------------------" + str(x)
            print "Deleting: " + str(upc.PolyGUID) + str(upc.FMEAS2)
            upcur.deleteRow(upc)
del sql2, upc, upcur, x, lD, listDelete

The PolyGUIDs come from a polygon fc. Having the polygon guid in the fc, ResFinalC6.shp, means that during a LocateFeatureAlongARoute operation.. the record from the polygon had one or more than one resultant record. I need to get rid of the any other records if the result was more than one record. A polygon record intersected the route in more than one place (three times for the problem records). The outcome results in a field displaying the m-value where the intersect occurred. So what I did was for each unique value in PolyGUID get a UpdateCursor..sort the field that holds the M-value (because I need the record with the lowest m-value) and use the x counter to delete those PolyGUIDs that resulted in more than one record (all except the one with the lowest m-value..which is why I did the sort on the UpdateCursor) resulting from the query with the UpdateCursor.


The issue is that after the cursor has gone through record 1 and set x=1..then to record 2 and set x=2 and then delete record 2..the script gets to those PolyGUIDs that show up three times..my print statement gets hit and x gets set to x=3 but the record doesn't get deleted. I have ran this numerous times and it's always the same PolyGUIDs left and they all show up three times before the delete tries. In the python shell window where the printing happens the record 3 gets cursed but no delete.

Best Answer

Following up with some of the comments to your post, I've cleaned up your script a bit. There are some unnecessary variables and the logic is a bit cumbersome. I obviously don't have the shapefile that you are working with and haven't tested this with anything locally so it may not work for you right off the bat, but it should at least give us a good basis to get you going.

import arcpy

shp = r'C:\Trash\Nov2011\ResFinalC6.shp'
sql = " \"PolyGUID\" <> ''"

rows = arcpy.SearchCursor(shp, sql)
delList = []
for row in rows:
    delList.append(row.PolyGUID)
print len(delList)
del rows

rows = arcpy.UpdateCursor(shp, "#", "#", "#", "FMEAS2 A")
for row in rows:
    if row.PolyGUID in delList:
        print "Deleting: %s %s" % (row.PolyGUID,row.FMEAS2)
        rows.deleteRow(row)
del rows

EDIT:

Okay, I think I have a better handle on your process. This is not the most efficient way to do it as it will create a cursor for every PolyGUID whether or not it has duplicate entries, but it's a start... NOTE: Changed second cursor to an update cursor (13:06 EST)

import arcpy

shp = r'C:\Trash\Nov2011\ResFinalC6.shp'
sql = " \"PolyGUID\" <> ''"

#--First, lets get a complete list of all PolyGUIDs
rows = arcpy.SearchCursor(shp, sql)
polyguids = set()
for row in rows:
    polyguids.add(row.PolyGUID)
del rows

print len(polyGUIDs)

#--Now, lets iterate over each PolyGUID...
for guid in polyguids:

    #-we create a new cursor for each PolyGUID that will only return rows for that GUID
    sql = " \"PolyGUID\" = '%s'" % guid
    rows = arcpy.UpdateCursor(shp, sql, "#", "#", "FMEAS2 A")
    x = 0
    for row in rows:
        if x == 0:
            #-ignore the first record (since sorted by 'FMEAS2', first record is the one we want)
            x += 1
        else:
            #-if multiple records with same PolyGUID, delete them
            print "Deleting: %s %s" % (row.PolyGUID,row.FMEAS2)
            rows.deleteRow(row)
    del rows
Related Question