2

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.

4
  • I am not sure what the goal is or what is wrong with the code you posted (although at first glance I would say the use of multiple cursors is unnecessary), but if you are trying to get rid of duplicates, try the Delete Identical tool.
    – blah238
    Commented Nov 15, 2011 at 22:52
  • 1
    Why do you have a test for X in the deletion loop? You should never have more than one object in the second loop (on listDelete) because your sql statement queries a GUID, which should by nature make it impossible that you return more than one row for upcur.
    – Nathanus
    Commented Nov 15, 2011 at 22:54
  • Does this error out with other data sources (file GDB, etc)? I know there's a fix for shapefile cursors coming in the next 10.0 service pack. Commented Nov 15, 2011 at 23:23
  • @JasonScheirer No error and I successfully delete the second record in the returned UpdateCursor object but the third record doesn't get deleted for every unique PolyGUID where there are more than two matches. And I am able to iterate the third record because my print statement hits..it just doesn't delete.
    – Justin
    Commented Nov 16, 2011 at 16:57

1 Answer 1

5

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
5
  • Could go one step further: delList = set() and delList.add() instead of .append. Should run faster that way. Commented Nov 16, 2011 at 7:28
  • Thanks for the tip, I'm not familiar with that function... yet. Commented Nov 16, 2011 at 14:09
  • @Justin, are we on the right track here? I'm assuming that once you create your list (or set) of PolyGUID's to delete from "ResFinalC6.shp" you just want to go through and delete all features that match any of the id's in the list. Commented Nov 16, 2011 at 14:50
  • @Jason No. For each unique PolyGUID, I want to find if there are multiple records with the same PolyGUID, then sort by a field for those records who share a value in the field PolyGUID (which is not a guid anymore in this table) and then delete all but the first record after the sort. Thanks.
    – Justin
    Commented Nov 16, 2011 at 16:55
  • @Justin, did this help? Commented Nov 18, 2011 at 21:22

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.