I agree that I wasn't too keen on having to "consume the iterable" and reset it. I had tried the .next() approach and got the StopIteration error but wasn't quite sure how to handle it; thank you Bruce Harold for mentioning that. That last option with row = None is clever and seems to solve both problems; thanks for sharing.
Since the cursor itself will raise a StopIteration error if there isn't a row to request, I guess I don't understand the value of wrapping it in a generator function to raise a StopIteration error.
Another one is wrapping the cursor in a generator function and seeing if StopIteration is raised when you request a row.
As Xander Bakker points out, the geoprocessing tool approach to addressing your issue involves creating a feature layer and counting that, and then passing the feature layer to the search cursor if there are results.
Looking at it from purely a Python perspective, i.e., not involving geoprocessing tools, the major issue with the code provided is that it completely consumes the iterable to determine if there is just one or more records. There are several ways in Python to check if an iterable is empty and then do one thing or another depending on the results.
One approach that doesn't fully consume the iterable to check for the existence of items uses next() with a sentinel value:
s_cursor <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>in_table<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"*"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">with</SPAN> s_cursor<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">if</SPAN> next<SPAN class="punctuation token">(</SPAN>s_cursor<SPAN class="punctuation token">,</SPAN> None<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">is</SPAN> <SPAN class="operator token">not</SPAN> None<SPAN class="punctuation token">:</SPAN> s_cursor<SPAN class="punctuation token">.</SPAN>reset<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> s_cursor<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">print</SPAN> row <SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"Cursor is empty!"</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Another approach sets the variable for holding what is returned by the iterable to a sentinel value and then checks after processing the iterable to see if anything was processed:
row <SPAN class="operator token">=</SPAN> None <SPAN class="keyword token">with</SPAN> s_cursor<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> s_cursor<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">print</SPAN> row <SPAN class="keyword token">if</SPAN> row <SPAN class="keyword token">is</SPAN> None<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"Cursor is empty!"</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
To check if a applying a where clause returns no results can also be done with the GetCount tool. Just make a featurelayer and check the result. Below some examples including using the search cursor on empty results, which really is no problem at all.
<SPAN class="keyword token">def</SPAN> <SPAN class="token function">main</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">import</SPAN> arcpy fc1 <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'D:\Xander\GeoNet\Ellipse\data.gdb\Ellipses'</SPAN> fc2 <SPAN class="operator token">=</SPAN> r<SPAN class="string token">'D:\Xander\GeoNet\Ellipse\data.gdb\Ellipses_empty'</SPAN> <SPAN class="comment token"># get count on a featureclass</SPAN> cnt1 <SPAN class="operator token">=</SPAN> getCount<SPAN class="punctuation token">(</SPAN>fc1<SPAN class="punctuation token">)</SPAN> cnt2 <SPAN class="operator token">=</SPAN> getCount<SPAN class="punctuation token">(</SPAN>fc2<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"fc1 has {0} features"</SPAN><SPAN class="punctuation token">.</SPAN>format<SPAN class="punctuation token">(</SPAN>cnt1<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"fc2 has {0} features"</SPAN><SPAN class="punctuation token">.</SPAN>format<SPAN class="punctuation token">(</SPAN>cnt2<SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># Cursor on a featureclass with features</SPAN> max_oid <SPAN class="operator token">=</SPAN> None <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc1<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">'OID@'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> curs<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> curs<SPAN class="punctuation token">:</SPAN> oid <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> max_oid <SPAN class="keyword token">is</SPAN> None<SPAN class="punctuation token">:</SPAN> max_oid <SPAN class="operator token">=</SPAN> oid <SPAN class="keyword token">elif</SPAN> oid <SPAN class="operator token">></SPAN> max_oid<SPAN class="punctuation token">:</SPAN> max_oid <SPAN class="operator token">=</SPAN> oid <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"max_oid for fc1:"</SPAN><SPAN class="punctuation token">,</SPAN> max_oid <SPAN class="comment token"># Cursor on a featureclass without features</SPAN> max_oid <SPAN class="operator token">=</SPAN> None <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc2<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">'OID@'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> curs<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> curs<SPAN class="punctuation token">:</SPAN> oid <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> max_oid <SPAN class="keyword token">is</SPAN> None<SPAN class="punctuation token">:</SPAN> max_oid <SPAN class="operator token">=</SPAN> oid <SPAN class="keyword token">elif</SPAN> oid <SPAN class="operator token">></SPAN> max_oid<SPAN class="punctuation token">:</SPAN> max_oid <SPAN class="operator token">=</SPAN> oid <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"max_oid for fc2:"</SPAN><SPAN class="punctuation token">,</SPAN> max_oid <SPAN class="comment token"># get count on a feature layer (with where clause)</SPAN> where <SPAN class="operator token">=</SPAN> <SPAN class="string token">"Ellipse = 1"</SPAN> fl1 <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>MakeFeatureLayer_management<SPAN class="punctuation token">(</SPAN>fc1<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"flay1"</SPAN><SPAN class="punctuation token">,</SPAN> where<SPAN class="punctuation token">)</SPAN> fl2 <SPAN class="operator token">=</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>MakeFeatureLayer_management<SPAN class="punctuation token">(</SPAN>fc2<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"flay2"</SPAN><SPAN class="punctuation token">,</SPAN> where<SPAN class="punctuation token">)</SPAN> cnt1 <SPAN class="operator token">=</SPAN> getCount<SPAN class="punctuation token">(</SPAN>fl1<SPAN class="punctuation token">)</SPAN> cnt2 <SPAN class="operator token">=</SPAN> getCount<SPAN class="punctuation token">(</SPAN>fl2<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"fl1 has {0} features"</SPAN><SPAN class="punctuation token">.</SPAN>format<SPAN class="punctuation token">(</SPAN>cnt1<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"fl2 has {0} features"</SPAN><SPAN class="punctuation token">.</SPAN>format<SPAN class="punctuation token">(</SPAN>cnt2<SPAN class="punctuation token">)</SPAN> <SPAN class="comment token"># Cursor on a featurelayer (where clause) with features</SPAN> max_oid <SPAN class="operator token">=</SPAN> None <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fl1<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">'OID@'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> curs<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> curs<SPAN class="punctuation token">:</SPAN> oid <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> max_oid <SPAN class="keyword token">is</SPAN> None<SPAN class="punctuation token">:</SPAN> max_oid <SPAN class="operator token">=</SPAN> oid <SPAN class="keyword token">elif</SPAN> oid <SPAN class="operator token">></SPAN> max_oid<SPAN class="punctuation token">:</SPAN> max_oid <SPAN class="operator token">=</SPAN> oid <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"max_oid for fl1:"</SPAN><SPAN class="punctuation token">,</SPAN> max_oid <SPAN class="comment token"># Cursor on a featureclass (where clause) with features, but without results</SPAN> where <SPAN class="operator token">=</SPAN> <SPAN class="string token">"Ellipse = -1"</SPAN> <SPAN class="comment token"># there are no features witch match this where clause</SPAN> max_oid <SPAN class="operator token">=</SPAN> None <SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>fc1<SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="string token">'OID@'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">,</SPAN> where<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> curs<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> curs<SPAN class="punctuation token">:</SPAN> oid <SPAN class="operator token">=</SPAN> row<SPAN class="punctuation token">[</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">]</SPAN> <SPAN class="keyword token">if</SPAN> max_oid <SPAN class="keyword token">is</SPAN> None<SPAN class="punctuation token">:</SPAN> max_oid <SPAN class="operator token">=</SPAN> oid <SPAN class="keyword token">elif</SPAN> oid <SPAN class="operator token">></SPAN> max_oid<SPAN class="punctuation token">:</SPAN> max_oid <SPAN class="operator token">=</SPAN> oid <SPAN class="keyword token">print</SPAN> <SPAN class="string token">"max_oid for fc1 (with where clause, no match):"</SPAN><SPAN class="punctuation token">,</SPAN> max_oid <SPAN class="keyword token">def</SPAN> <SPAN class="token function">getCount</SPAN><SPAN class="punctuation token">(</SPAN>fc<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">return</SPAN> int<SPAN class="punctuation token">(</SPAN>arcpy<SPAN class="punctuation token">.</SPAN>GetCount_management<SPAN class="punctuation token">(</SPAN>fc<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">.</SPAN>getOutput<SPAN class="punctuation token">(</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">if</SPAN> __name__ <SPAN class="operator token">==</SPAN> <SPAN class="string token">'__main__'</SPAN><SPAN class="punctuation token">:</SPAN> main<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
This will print:
fc1 has <SPAN class="number token">722</SPAN> features fc2 has <SPAN class="number token">0</SPAN> features max_oid <SPAN class="keyword token">for</SPAN> fc1<SPAN class="punctuation token">:</SPAN> <SPAN class="number token">722</SPAN> max_oid <SPAN class="keyword token">for</SPAN> fc2<SPAN class="punctuation token">:</SPAN> None fl1 has <SPAN class="number token">361</SPAN> features fl2 has <SPAN class="number token">0</SPAN> features max_oid <SPAN class="keyword token">for</SPAN> fl1<SPAN class="punctuation token">:</SPAN> <SPAN class="number token">361</SPAN> max_oid <SPAN class="keyword token">for</SPAN> fc1 <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">with</SPAN> where clause<SPAN class="punctuation token">,</SPAN> no match<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> None<SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
I know I'm playing necromancer and raising this discussion from the dead but I was looking for an answer to this question and found my own solution that I thought I would post. Maybe someone else has come up with something better by now.
Thanks to Joshua Bixby for his blog post on cursors, here's what I came up with:
<SPAN class="keyword token">with</SPAN> arcpy<SPAN class="punctuation token">.</SPAN>da<SPAN class="punctuation token">.</SPAN>SearchCursor<SPAN class="punctuation token">(</SPAN>in_table<SPAN class="punctuation token">,</SPAN> <SPAN class="string token">"*"</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">as</SPAN> s_cursor<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">if</SPAN> sum<SPAN class="punctuation token">(</SPAN><SPAN class="number token">1</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> s_cursor<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="comment token">## Counts items in cursor, returns 0 if empty</SPAN> s_cursor<SPAN class="punctuation token">.</SPAN>reset<SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="comment token">## Return cursor back to the first row after counting</SPAN> <SPAN class="keyword token">for</SPAN> row <SPAN class="keyword token">in</SPAN> s_cursor<SPAN class="punctuation token">:</SPAN> <SPAN class="comment token"># Process rows</SPAN> <SPAN class="keyword token">print</SPAN><SPAN class="punctuation token">(</SPAN>row<SPAN class="punctuation token">)</SPAN> <SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">print</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">"Cursor is empty!"</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
The check for rows will iterate through the cursor leaving nothing for the .next() item so you have to .reset() the cursor to start from the beginning again. In my case, I couldn't just count the rows with GetCount_management() in the original feature class because I was using a where clause in the search cursor.
if arcpy.SearchCursor(myTable, sql_statement).next() == None: print "Empty cursor!"
import types import arcpy as ap rows = ap.SearchCursor(myTable, sql_statement) row = rows.next() if type(row) != types.NoneType: # do a bunch of work
row, rows= None, None rows= arcpy.SearchCursor(inputFC) for row in rows: -- do work--- del row, rows
rowCount = 0 row, rows= None, None rows= arcpy.SearchCursor(inputFC) for row in rows: rowCount += 1 -- do work--- del row, rows
If your cursor is empty, it will never step in. Nothing in the loopfor row in rows:will execute because there is no row in rows, if you follow.So I tested your code and came back with 4 rows, is that right? i am confused, I thought you wanted to test if the cursor object was empty?
for row in rows:
#STEP1: Execute a SQL query (the MakeFeatureLayer tools is probably the quickest way to do this) arcpy.MakeFeatureLayer_management(indxTileFC, indxTileFL, "HCPUNIT_NM <> 'OESF') #STEP2: Are any records returned? If 0 records satisfy the SQL query, then let us know! If 0 records are returned, the SQl query is probably incorrect!!! if int(arcpy.GetCount_management(indxTileFL).getoutput(0)) == 0: print "Query returned no records!" #STEP3: If there are records returned by the query, then run a search cursor and look for Null field values in MY_FIELD else: #Create a search cursor object using the same query as the one in the MakeFeatureLayer searchRows = arcpy.SearchCursor(indxTileFC, "HCPUNIT_NM <> 'OESF') #For each row in the collection of search cursor rows for searchRow in searchRows: #if the value in the "MY_FIELD" field is Null let us know... If theer are no Null values in the MY_FIELD field, then no message will be printed. if searchRow.MY_FIELD == None: #Another way: if searchRow.isNull("MY_FIELD") == True: print "MY _FIELD is Null!" #Delete the search cursor objects so the read lock is released on the search cursor table del searchRow, searchRows
import arcgisscripting gp = arcgisscripting.create(9.3) table = 'C:/Users/lilaandmax/Downloads/AttributeCrosswalk.dbf' ####### the following three0FC works three0FC = 'AirfieldSurface' ######## but if you do this, three0FC = 'XAirfieldSurface' ## nothing happens query = "Three0FCla = '" + three0FC + "'" row, rows = None, None rows = gp.SearchCursor(table, query) for row in rows: if row.isNull("Three0FCla"): print "isNull" elif row == None: print "None" elif row == "": print "emptyspace" else: print row.getValue("Three0FCla")
arcpy.MakeFeatureLayer_management(indxTileFC, indxTileFL, "HCPUNIT_NM <> 'OESF'); showGpMessage() if int(arcpy.GetCount_management(indxTileFL).getoutput(0)) == 0: print "Query returned no records!" else: #if there are records returned by the query, then run a search cursor and look for Null field values in MY_FIELD searchRows = arcpy.SearchCursor(indxTileFC, "HCPUNIT_NM <> 'OESF') for searchRow in searchRows: if searchRow.MY_FIELD == None: #Another way: if searchRow.isNull("MY_FIELD") == True: print "MY _FIELD is Null!" del searchRow, searchRows
checkvar = "cursor empty" rows = arcpy.SearchCursor(fc, query) for row in rows: if checkvar == "cursor empty": checkvar = "cursor full" print checkvar
row = None rows = arcpy.SearchCursor(fc, query) for row in rows: #cursor things if not row: print "cursor was empty"
Signed in members can post, follow updates, and more. New here? Register a free account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.