arcpy.da Cursors and Readability Part 2
arcpy.da cursors provide the simplest data structure by default (tuples). Python generators provide a pretty neat way of customizing these cursors to increase readability.
SearchCursor:
Return dict
instead of tuple:
def rows_as_dicts(cursor):
""" returns rows as dicts (does not maintain field order) """
colnames = cursor.fields
for row in cursor:
yield dict(zip(colnames, row))
Usage (note the cursor is wrapped with the generator):
total_cost_by_name = {}
with arcpy.da.SearchCursor(costs_table, ["name", "unit_cost", "quantity"]) as curs:
for row in rows_as_dicts(curs):
total_cost_by_name[row["name"]] = row["unit_cost"] * row["quantity"]
If using with an update cursor, you’ll want to use an OrderedDict so the field/value order is maintained. You’ll also need to the use dict.values()
to pass an ordered tuple back into Cursor.updateRow.
UpdateCursor:
Return collections.OrderedDict
instead of tuple:
import collections
def rows_as_ordered_dicts(cursor):
""" returns rows as collections.OrderedDict """
colnames = cursor.fields
for row in cursor:
yield collections.OrderedDict(zip(colnames, row))
Usage (updating):
with arcpy.da.UpdateCursor(costs_table, ["unit_cost", "quantity", "total_cost"]) as curs:
for row in rows_as_ordered_dicts(curs):
row["total_cost"] = row["unit_cost"] * row["quantity"]
# call .values() to convert back to tuple
# if we didn't use OrderedDict, the values would be in random order.
curs.updateRow( row.values() )