The SearchCursor syntax in the previous comments and posts is outdated and 10 times slower than a data access cursor if you have Desktop 10.1 or later. Only use DA cursors.
Here is my script, assuming your categories of banks and churches are in the same field in the feature class, this script will get the top ten items for all categories or only specified categories if you use that option. The end of the script will create a separate feature class of the top 10 items for all specified categories that will be sorted by category and then by distance. It performs at least 10 times faster than sorting a cursor.
print "Script Set Up"
import arcpy
# User defined variables
# substitute your workspace
ws = r"C:\Path\OptionalGDB.gdb"
# substitute your your input and output feature classes
sourceFC = "Feature_Class"
outDataset = "Feature_Class_TOP_10s"
# substitute your Field names for the Category and Distance values
Category = "CATEGORY_FIELD"
Distance = "DISTANCE FIELD"
# Optionally remove comment from second line and modify to list specific categories
categorySet = ''
# categorySet = Category " IN ('BANKS', 'CHURCHES') AND "
### Scripted routine that should not need editing
# Set the workspace
arcpy.env.workspace = ws
# Make a feature layer for selecting records
sourceLayer = sourceFC + "Layer"
arcpy.MakeFeatureLayer_management(sourceFC, sourceLayer)
# Build a where clause
whereclause = categorySet + "OBJECTID > -1"
# select records based on the where clause
arcpy.SelectLayerByAttribute_management(sourceLayer, "NEW_SELECTION", whereclause)
# field list to be ordered by Category then Distance then OBJECTID
fields = [Category, Distance, "OID@"]
print "Reading records"
# Build a summary dictionary from a da SearchCursor for each category.
valueDict = {}
with arcpy.da.SearchCursor(sourceLayer, fields) as searchRows:
for searchRow in searchRows:
keyValue = searchRow[0]
if not keyValue in valueDict:
# assign a new Category to the dictionary storing a sortable string list
valueDict[keyValue] = ["%(Cat)s,%(Dist)031.15f,%(OID)020.0f" % {'Cat': searchRow[0], 'Dist' : searchRow[1], 'OID' : searchRow[2]}]
else:
# when a Category is already in the dictionary append to the list
valueDict[keyValue].append("%(Cat)s,%(Dist)031.15f,%(OID)020.0f" % {'Cat': searchRow[0], 'Dist' : searchRow[1], 'OID' : searchRow[2]})
print "Finished Reading Records"
# Build a where clause
whereclause = "OBJECTID IN ("
for item in sorted(valueDict.keys()):
i = 0
OIDS = ""
for OID in sorted(valueDict[item]):
OIDS += str(int(OID.split(",")[2])) + ","
whereclause += str(int(OID.split(",")[2])) + ","
i += 1
if i >= 10:
break
print str(OID.split(",")[0]) + " OBJECTIDs - " + OIDS[:-1]
print ""
whereclause = whereclause[:-1] + ")"
print whereclause
# select records based on the where clause
arcpy.SelectLayerByAttribute_management(sourceLayer, "NEW_SELECTION", whereclause)
### Optional section for creating a sorted feature class of top 10 items
### Delete the output table if it exists
if arcpy.Exists(outDataset):
arcpy.Delete_management(outDataset)
### Set Order of features to be first by Category and then by Distance
sort_fields = [[Category, "ASCENDING"], [Distance, "ASCENDING"]]
### Output Sorted Selected top 10 Features for all categories
arcpy.Sort_management(sourceLayer, outDataset, sort_fields)
If you want to process the top 10 items of each category separately then revise the end of the script to:
for item in sorted(valueDict.keys()):
i = 0
OIDS = ""
# Build a where clause
whereclause = "OBJECTID IN ("
for OID in sorted(valueDict[item]):
OIDS += str(int(OID.split(",")[2])) + ","
whereclause += str(int(OID.split(",")[2])) + ","
i += 1
if i >= 10:
break
print str(OID.split(",")[0]) + " OBJECTIDs - " + OIDS[:-1]
print ""
whereclause = whereclause[:-1] + ")"
print whereclause
# select records based on the where clause
arcpy.SelectLayerByAttribute_management(sourceLayer, "NEW_SELECTION", whereclause)
# Do something with the current category top 10 selection at this indent level