1

I would like to search all feature classes in a geodatabase using a search cursor but I want to use two separate where clauses. I'm gathering information about a particular field and I need to know how it is different for each where clause.

The first where clause would be:

GIS_STATUS = 'Superseded'

and the other would be:

GIS_STATUS <> 'Superseded'

My suspicion is that I need to traverse the entire geodatabase twice using two loops. However, I wonder if there a way I can use two simultaneous search cursors? Parallel search cursors?

I'm using ArcGIS Desktop 10.4.1.


There seemed to be a bit of confusion about what I was trying to do, so I'll show what I had in mind.

Firstly, I define two sets. One to hold the values in the METADATA field where GIS_STATUS = 'Superseded' and another where GIS_STATUS <> 'Superseded'.

superSet = set()
notSuperSet = set()

Then, I loop through all feature classes twice. One for each where clause:

for dirpath, dirnames, filenames in arcpy.da.Walk(env.workspace, datatype = 'FeatureClass'):
    for filename in filenames:
        with arcpy.da.SearchCursor(filename, "METADATA", """GIS_STATUS = 'Superseded'""") as sCur:
            for row in sCur:
                superSet.add(row[0])

and

for dirpath, dirnames, filenames in arcpy.da.Walk(env.workspace, datatype = 'FeatureClass'):
    for filename in filenames:
        with arcpy.da.SearchCursor(filename, "METADATA", """GIS_STATUS <> 'Superseded'""") as sCur:
            for row in sCur:
                notSuperSet.add(row[0])

Then, I can use the set methods to determine how they are different.

superSet.difference(notSuperSet)

So, my question is: is this the best way to do this? Do I need two loops?

  • I don't think there is ever a need to. Instead I would use list (sometimes dictionary) comprehension on one SearchCursor first, and then retrieve values from the list (or dictionary) when using the other SearchCursor. – PolyGeo Oct 26 '16 at 6:48
  • @PolyGeo, I don't think that will work. The results of both search cursors will necessarily be different. – Fezter Oct 26 '16 at 6:49
  • Without seeing a code snippet it's hard to say more but I used to often think I might need simultaneous cursors but once I started using list (sometimes dictionary) comprehensions that thought evaporated. Just double-checking that you know arcpy.da.SearchCursor() can take a where_clause. – PolyGeo Oct 26 '16 at 6:53
  • Yes, I'm aware search cursors can take where clauses. I need to run the search cursor using the first clause, and then again with the second. Just wanted to see if I could do it simultaneously. – Fezter Oct 26 '16 at 6:56
  • 3
    As with most "Is it possible" questions, the answer is "Yes", but I question the need -- If you need all the rows anyway just use one cursor with an if test. Note that there is a difference between "simultaneously open" and "parallel" that can't be realized in a non-threadwd language. – Vince Oct 26 '16 at 10:53
4

It turns out I was thinking about this the wrong way. I was trying to run two search cursors when I could do what I needed with one. Thanks to @Vince for the clarification.

I just create two empty sets prior to looping through my file geodatabase:

superSet = set()
notSuperSet = set()

Then, I just use one loop but include the GIS_STATUS field in the search cursor. Then, use an if/else statement to determine whether GIS_STATUS was 'Superseded' or not.

for dirpath, dirnames, filenames in arcpy.da.Walk(env.workspace, datatype = 'FeatureClass'):
    for filename in filenames:
        with arcpy.da.SearchCursor(filename, ["METADATA","GIS_STATUS"]) as sCur:
            for row in sCur:
                if row[1] == 'Superseded':
                    superSet.add(row[0])
                else:
                    notSuperSet.add(row[0])

The results are almost twice as fast as the original two loops (which is expected).

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.