4

When performing a query like this:

var = 2

with arcpy.da.SearchCursor(in_table="table", field_names=['c1','c2'], where_clause = '[c1]' + '=' '\'' + str(var) +'\'') as cursor:

I've just simply been doing a for loop below this to do a bit of value checking.

var = 2

with arcpy.da.SearchCursor(in_table="table", field_names=['c1','c2'], where_clause = '[c1]' + '=' '\'' + str(var) +'\'') as cursor:
     for x in cursor:
         if x[1] != 1:
              print whatever

Is it possible to eliminate the for loop by doing something like:

  if cursor[0][1] !=1:
     print whatever

I may not be understanding this fully, but is this query not storing the columns that I have specified as an array into the variable cursor? And should I not be able to reference the second column of the query utilizing cursor[0][1]?

I've tested this out and it doesn't work, so I'm guessing that it's not doing what I'm expecting to do so, I just do not know how to access the result without doing a for-loop.

Sorry if this question is confusing.

  • 1
    Use table to numpy array instead. – FelixIP Apr 5 '18 at 20:34
  • 7
    For most intents, treat cursor like a generator that yields tuples. – Paul Apr 5 '18 at 20:36
  • What is your ultimate objective? Why do you not want to access the rows using a for loop? – Aaron Apr 5 '18 at 21:32
  • 4
    Even though a cursor is iterated like a tuple or list it's not a tuple or list, it's a cursor! A cursor object can be iterated because it implements iterable, but not addressed because it doesn't implement that property, cursors also have their own methods (update, insert etc..) and doesn't have tuple/list methods like append... cursors walk like a duck but don't quite quack like a duck, so it's not a duck. – Michael Stimson Apr 5 '18 at 21:45
  • What do you mean by "array"? There's an array type in Python, but it's quite uncommon to use it. The typical mutable sequence structure is list. – jpmc26 Apr 6 '18 at 2:50
9

As described in SearchCursor-Help, SearchCursor returns iterator. It means that you cannot use cursor[0][1]. In any case, you have to use for loop to iterate over features.

But using list comprehension may help you a little:

from arcpy.da import SearchCursor

var = 2
# features with c1=2
whereClause = '[c1]' + '=' '\'' + str(var) +'\''

# get all (c1,c2) pairs, if c2!=1
# list comprehension
cursor = [ x for x in SearchCursor("table", ['c1','c2'], whereClause) if x[1]!=1 ]

# then, cursor list have all '(c1,c2) value pairs' of features with c2!=1
# in your case, all cursor[i][0] equals 2 because whereClause equals 'c1=2'
# all cursor[i][1] doesn't equal 1. 
# for example: cursor = [(2, 0), (2, 10), (2, 7), (2, 200), ...]
  • 5
    You could shorten the main line there to be cursor = [x for x in SearchCursor("table" , ['c1','c2'], whereClause) if x[1] !=1]. You don't have to re-assign the values of a SearchCursor returned tuple to a new tuple. – John Apr 5 '18 at 21:50
  • 1
    Oo. @John is right, thank him. I editted the answer as he states. – Kadir Şahbaz Apr 5 '18 at 21:54
  • Thank you. I think this accomplishes what I was doing more efficiently! – shane Apr 6 '18 at 13:24
7

If you want to work with feature attributes as an array and do away with the computationally expensive for loop, you can use TableToNumPyArray() to convert the attributes to a numpy array. This unleashes the full numpy arsenal. For example:

import arcpy
import numpy as np

fc = r'C:\path\to\your\geodb.gdb\featureclass'
array = arcpy.da.TableToNumPyArray(fc, "*")

Let's look at the structure of the numpy array:

>>> array
array([ (1, [-90.76623071185851, 48.05919100478101], 1.6963634949176454, 0.22899603992269765, 1, -90.76623071185851, 48.05919100478101, u'12:01'),
       (2, [-92.53108497604227, 47.732022361872], 1.7467078562344307, 0.2427899374179541, 2, -92.53108497604227, 47.732022361872, u'12:02'),
       (3, [-91.73610910364329, 46.58834277058802], 2.182985003705143, 0.37922035507660834, 3, -91.73610910364329, 46.58834277058802, u'12:03'),
       (4, [-88.74246771509985, 46.15461041370514], 2.847861592720326, 0.6453984129693076, 4, -88.74246771509985, 46.15461041370514, u'12:04'),
       (5, [-88.39081946312274, 47.42135644145347], 3.038898807952548, 0.7348904666573336, 5, -88.39081946312274, 47.42135644145347, u'12:05'),
       (6, [-89.14675937270161, 48.526768055705695], 2.7076341063329634, 0.5834049208607849, 6, -89.14675937270161, 48.526768055705695, u'12:06'),
       (7, [-90.56562763766716, 47.32958486445008], 2.915101303346966, 0.676234679810017, 7, -90.56562763766716, 47.32958486445008, u'12:07'),
       (8, [-93.81217334723218, 46.916116897213875], 1.9081371199688988, 0.2897405607664292, 8, -93.81217334723218, 46.916116897213875, u'12:08'),
       (9, [-91.97128321056668, 45.9718603576183], 2.221744769908184, 0.3928063220556296, 9, -91.97128321056668, 45.9718603576183, u'12:09'),
       (10, [-90.70904602560582, 45.73189770788447], 1.0070513913079986, 0.08070369208883092, 10, -90.70904602560582, 45.73189770788447, u'12:10')], 
      dtype=[('OBJECTID', '<i4'), ('SHAPE', '<f8', (2,)), ('SHAPE_Length', '<f8'), ('SHAPE_Area', '<f8'), ('VEHICLEID', '<i4'), ('NEAR_X', '<f8'), ('NEAR_Y', '<f8'), ('TIME', '<U50')])
>>> 

To get the first row and second column value as in your example, you can use:

>>> print(array[0][1])
[-90.76623071  48.059191  ]
>>> 

Here is an example of a query within the OBJECTID column:

>>> np.where(array["OBJECTID"] > 5 )
(array([5, 6, 7, 8, 9]),)
>>> 

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.