A handy wildcard tip

As you know, the arcpy module provides functions built specifically for listing data so it can be iterated through during processing. All these list functions can be passed a wildcard argument which filters what is returned. For example, if you only require feature classes that start with a prefix of “tax”, you would do this:

# Set the workspace. List all feature classes that start with 'tax'.
arcpy.env.workspace = "d:/stjohns/localgovernment.gdb"
fcs = arcpy.ListFeatureClasses("tax*")

However, what if you wanted to retrieve all feature classes which do not start with “tax”? Here is a handy trick for doing it:

arcpy.env.workspace = "d:/stjohns/localgovernment.gdb"
fcs = [fc for fc in arcpy.ListFeatureClasses() if not fc.startswith('tax')]

If “tax” was a suffix, use endswith:

fcs = [fc for fc in arcpy.ListFeatureClasses() if not fc.endswith('tax')]

Recursive list feature classes

UPDATE: At 10.1 service pack 1, this can be more easily achieved using arcpy.da.Walk. Also see Inventorying data.

The following function (recursive_list_fcs) will return a list of all feature classes that fall under the input workspace, including those not seen by the file system such as in a file geodatabase.

import os
import arcpy


def recursive_list_fcs(workspace, wild_card=None, feature_type=None):
    """Returns a list of all feature classes in a tree.  Returned
    list can be limited by a wildcard, and feature type.
    """
    preexisting_wks = arcpy.env.workspace
    arcpy.env.workspace = workspace

    try:
        list_fcs = []
        for root, dirs, files in os.walk(workspace):
            arcpy.env.workspace = root
            fcs = arcpy.ListFeatureClasses(wild_card, feature_type)
            if fcs:
                list_fcs += [os.path.join(root, fc) for fc in fcs]

            # Pick up workspace types that don't have a folder
            #  structure (coverages, file geodatabase do)
            workspaces = set(arcpy.ListWorkspaces()) - \
                         set(arcpy.ListWorkspaces('', 'FILEGDB')) -\
                         set(arcpy.ListWorkspaces('', 'COVERAGE'))

            for workspace in workspaces:
                arcpy.env.workspace = os.path.join(root, workspace)
                fcs = arcpy.ListFeatureClasses(wild_card,
                                               feature_type)

                if fcs:
                    list_fcs += [os.path.join(root, workspace, fc)
                                 for fc in fcs]

            for dataset in arcpy.ListDatasets('', 'FEATURE'):
                ds_fcs = arcpy.ListFeatureClasses(wild_card,
                                                  feature_type,
                                                  dataset)
                if ds_fcs:
                    list_fcs += [os.path.join(
                        root, workspace, dataset, fc)
                                 for fc in ds_fcs]

    except Exception as err:
        raise err
    finally:
        arcpy.env.workspace = preexisting_wks

    return list_fcs