Python won't continue to the third loop/update cursor

930
3
04-02-2014 08:41 AM
GrljAles
Occasional Contributor
Hi,

Can someone look at my code and tell me why it is not working:

try:      
    with arcpy.da.SearchCursor("selectingBufferLayer", isSelectorField) as cursor:
        for row in cursor:
            oid = int(row[1])
            if (row[0] >= 1.5):
                arcpy.SelectLayerByAttribute_management("selectingBufferLayer", "NEW_SELECTION", '"ID" = {}'.format(oid))
                print "Selected row No. " + str(oid) + " by attributes."
                arcpy.SelectLayerByLocation_management("depressionsLayer", "INTERSECT", "selectingBufferLayer")
                print "Selected row by No. " + str(oid) + " by location."
                arcpy.Append_management("depressionsLayer", depressionsLocation + "firstResults.shp", "NO_TEST", "", "")
                print "Appended selected rows to new shapefile."
        
                with arcpy.da.SearchCursor("depressionsFIDLayer", wasSelectedField) as selcursor:
                    for selrow in selcursor:
                        arcpy.SelectLayerByAttribute_management("depressionsFIDLayer", "NEW_SELECTION", '"ID" = {}'.format(oid))
                        arcpy.Append_management("depressionsFIDLayer", depressionsLocation + "firstResults.shp", "NO_TEST", "", "")
                        print "Exporting depressions that were selected by depression No. " + str(oid)
                        

                        with arcpy.da.UpdateCursor(caveFID, caveFIDField) as cavecursor:
                            for caverow in cavecursor:
                                if row[0] == 999999999:
                                    row[0] = oid
                                    cursor.updateRow(caverow)
                                    print "Updating CaveFid."
                                    break

        del cursor, row
finally: 
    if arcpy.Exists("depressionsLayer"): arcpy.Delete_management("depressionsLayer")
    if arcpy.Exists("selectingBufferLayer"): arcpy.Delete_management("selectingBufferLayer")
    if arcpy.Exists("depressionsFIDLayer"): arcpy.Delete_management("depressionsFIDLayer")


What I would like achieve: First search cursor will select single row, that has row[0]>=1.5. Then with this selection a select by location will be performed and the selected elements will be exported/appended to the new shapefile.

The second loop will select an element that has the same ID as selecting feature from select by location from previous loop and append it to the same shapefile as before.

Lastly the third loop will update field in the shapefile that contains appended records with the ID of the selecting feature from the first loop if the current value in that field is 999999999.

The problem is that process passes through the first loop succesfully but then iterates through second loop for many times every time appending the same polygon. I would like it to go through first cursor once, continue to the second cursor and execute it once and then the same for last cursor. Afted that it is supposed to return back to the first cursor repeating the process.
Tags (2)
0 Kudos
3 Replies
markdenil
Occasional Contributor III
It is not immidiatly obvious what you are trying to do, but
Don't it this way.
You are attempting to run feature class / table layer actions inside cursors
which are accessing the table by row.
Plus running a cursor inside a cursor inside another cursor

It is awakward, messy, and is quite likely to end in tears.

I suggest you run each cursor individually.
Use the first search cursor to build a dictionary of significant row values
keyed to ... maybe the oids from "selectingBufferLayer"

use the dictionary to run a loop to create feature layers to replace the the selects by attribute
and the layers to do the select by location, and make a new feature layers from each result.
Then do the appends from the output layers.


Consider what is happening here:
why, for example, do you even need a seartch cursor on "depressionsFIDLayer"?
you are not actually doing anything to the row returned by the cursor
The cursor is just counting, and for no logical reason I can see.

You are selecting from depressionsFIDLayer on the oid of selectingBufferLayer,
and you are not even accessing any of the values in selrow (the row from depressionsFIDLayer)

....
0 Kudos
GrljAles
Occasional Contributor
Well I'm new to python and I thougt this would work and it were until I wrote that last loop. And you are right, the second loop is not needed, as I eliminated it and it works anyway but the Update cursor is still ignored.

I'm not familiar with dictionaries... Could you explain a litle? I googled it but I can't really understand what they do and what is their advantage.

Anyway, should I eleiminate the last loop also and use for example field calculator to update the caveFIDField?
0 Kudos
markdenil
Occasional Contributor III
a dictionary allows you to store (just about) anything,
and retrive it using a key word.
aDict = {
    'Bob': [a, b, c, d],
    'Carol': ['aaa', 'bbb', 'ccc'],
    'Ted': {"this": "THAT",
            "the": "OTHER"},
    'Alice': "Go ask Alice"
    }

aDict has four keys that each hold differen things,
lists of variables or strings, or, for Ted, another dictionary.

access the dictionary by the key:
>>> aDict['Carol']
['aaa', 'bbb', 'ccc']
>>> aDict['Ted']['this']
'THAT'
>>> 


you can use the search cursor to create a dictionary entry keyed to each oid
if row[0] not in aDict:
 aDict[row[0]] = [row[0], row[1], row[2]]


Note, it is better to assign the row value to a real variable if you are going to want to reference it more than once.
it just works better...


make a list of the keys with
listOfKeys = aDict.keys()

Then you can loop through the list, accessing each row of values
to populate the arguments for the make feature layer (to gather more information, for example)
and ultimatly to provide the values for your update cursor.
0 Kudos