I need to find a way to find a specific value in the attribute table and then export all rows with said value to a new feature class.

Below is the code that I have managed to come up with (using other answers on this site). It gives the FID of the rows with the value searched but I can't find a way to select and export those records to a new file.

import arcpy
arcpy.env.overwriteOutput = True

# Set the environment
workspace = r"\\C:\\GIS\\"
arcpy.env.workspace = workspace
fc = "species.shp"

# Get fields in the attribute table
field_names = [f.name for f in arcpy.ListFields(fc, field_type='String')]

# Loop through fields
for field in field_names:
    # Create a search cursor through rows in the feature class that looks for "In Danger" values and prints the record's FID number
    search = arcpy.da.SearchCursor(fc, "*")
    for row in search:
        if "In Danger" in row:
            print("In Danger value for FID {0}".format(row[0]))
            arcpy.Select_analysis(fc, 'new_fc', '{} like \'%{}%\''.format(field, 'In Danger'))
  • 3
    No need for a cursor - look into the Select (Analysis) tool. – PolyGeo Jul 8 '19 at 2:39
  • 1
    Be cautious of using both raw formatting and double-backslashes on paths -- using one or the other will cause fewer complications. – Vince Jul 8 '19 at 2:46
  • I just simplified the path for this example; I had some complications when I started. Thanks! – User1228a Jul 8 '19 at 2:48
  • I agree with PolyGeo, field_names = [f.name for f in arcpy.ListFields(fc, field_type = 'String')] then for field in field_names: arcpy.Select_analysis(fc,'Your Output','{} like \'*Danger*\''.format(field)) will find and export any features that have Danger in the field value - but beware some feature class storage types are case sensitive and some use * as a wildcard other use % as a wild card. – Michael Stimson Jul 8 '19 at 3:23
  • when I include the f.name for f in arcpy.ListFields, for some reason it prints all the values 8 times (once for every field in my table, I assume). But even then, arcpy.Select_analysis generates an empty shapefile. – User1228a Jul 8 '19 at 3:37

I usually list OIDs of the rows meeting some condition then select using these:

import arcpy

fc = r'C:\GIS\species.shp'

field_names = [f.name for f in arcpy.ListFields(fc) if f.type=='String']

oids_to_select = []
with arcpy.da.SearchCursor(fc,['OID@']+field_names) as cursor:
    for row in cursor:
        if 'In Danger' in row: #If in any of the listed field, append OID to list
        #If 'In Danger' can be a substring, for example 'ABC In Danger CDE' then try: if any(['In Danger' in substring for substring in row])

sql = "{0} IN{1}".format(arcpy.AddFieldDelimiters(fc,arcpy.Describe(fc).OIDFieldName),tuple(oids_to_select))
  • This code does exactly what I need. I have some many things to learn from here though. For instance, I still don't understand what is that f.name for f in in the 3rd line. I thought that arcpy.ListFieldds(fc) was enough for that. – User1228a Jul 8 '19 at 10:55
  • Nice. ListFields is listing field objects, not field names. But field object have properties like name and type which you can fetch using .name or .type. Input to the cursor need to be a list of field names so that line is listing the names using list comprehension. – BERA Jul 8 '19 at 11:00

I'd skip selection by using insert cursor, e.g.

import arcpy
from arcpy import env
env.overwriteOutput = True
arcpy.CopyFeatures_management(infc, outfc)
with arcpy.da.SearchCursor(infc,"*") as cursor:
    for row in cursor:
        if "In Danger" not in row:continue

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.