2

I've been working on this code for about 3 days and all of my time has been spent trying to understand why I can only execute the deleteRow() method on the first pair of cursors. The idea is that a cursor will iterate through the rows of a .dbf table and remove any rows whose attributes values in a dictionary created by the SearchCursor. Here is the applicable code:

with arcpy.da.SearchCursor(ParcelJoin, ["Name"]) as cursor:
    lookupTbl = {}
    for row in cursor:
        lookupTbl.update({row[0]:row[0]})

with arcpy.da.UpdateCursor(Foreclosure, ["Parcel"]) as cursor:
    for row in cursor:
        if row[0] in lookupTbl:
            cursor.deleteRow()
        else:
            continue
    print('Joined features have been removed!')

with arcpy.da.SearchCursor(AddressJoin, ["FullAddr"]) as cursor:
    for row in cursor:
        lookupTbl.update({row[0]:row[0]})

with arcpy.da.UpdateCursor(Foreclosure, ["Address"]) as cursor:
    for row in cursor:
        if row[0] in lookupTbl:
            cursor.deleteRow()
        else:
            continue
    print('Joined features have been removed!')

Foreclosure is a .dbf of property sales, ParcelJoin is a join between a parcel layer and the Foreclosure table based on ParcelID and AddressJoin is the same feature class joined on address.

The first iteration of the cursor pairing executes successfully and removes the relevant rows. However, the second pairing iterates properly (I've checked by creating a counter to see how many times the code iterates) but does not execute the deleteRow(). I've looked all over the web but can't find any examples of code that use two cursor pairs in this way.


Finally figured it out, there were trailing whitespaces in the Foreclosure table that needed to be stripped. Code with list comprehension works beautifully!

  • Just tried that in a separate script and saw no change. It may be a data error in the Foreclosure table which I'm investigating now. – J. Shep Apr 12 '18 at 18:23
3

This will create a dictionary where the keys are the same as the values which is useless: lookupTbl.update({row[0]:row[0]}).

Store the values in a list instead:

#List all names
Names = [i[0] for i in arcpy.da.SearchCursor(ParcelJoin,'Name')]

with arcpy.da.UpdateCursor(Foreclosure, "Parcel") as cursor:
    for row in cursor:
        if row[0] in Names:
            cursor.deleteRow()

print 'Joined features have been removed!'

(If you want to create a dictionary using cursors you need two or more fields in the cursor:

d = {key:value for (key,value) in arcpy.da.SearchCursor('Featureclass', ['Field1','Field2'])}

#Or
d = {}
with arcpy.da.SearchCursor('Featureclass', ['Field1','Field2']) as cursor:
    for row in cursor:
        d[row[0]]=row[1]

)

  • 1
    I had seen list comprehension methods but couldn't quite get the syntax to work, so thank you for that! However, my code is still ignoring the second delete despite my being able to identify matching records by printing row within the for loop and printing the resultant list and visually inspecting. – J. Shep Apr 12 '18 at 18:06
0

You say that you're visually inspecting the row values for matches, but are you verifying programmatically?

First, try this (which incorporates @BERA's list comprehension):

#List all addresses
Addrs = [i[0] for i in arcpy.da.SearchCursor(AddressJoin, ["FullAddr"])]

with arcpy.da.UpdateCursor(Foreclosure, ["Address"]) as cursor:
    for row in cursor:
        print row[0] in Addrs

If all the results are False then you know your matches are failing. If your matches are failing, then I suspect the culprit is whitespace or character encoding. You can account for both using a combination of str() and .strip() on both pieces of text:

#List all addresses
Addrs = [str(i[0]).strip() for i in arcpy.da.SearchCursor(AddressJoin, ["FullAddr"])]

with arcpy.da.UpdateCursor(Foreclosure, ["Address"]) as cursor:
    for row in cursor:
        if str(row[0]).strip() in Addrs:
            cursor.deleteRow()

    print('Joined features have been removed!')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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