The *
symbol indicates tuple unpacking. This can be very handy particularly when you have to call the same function many times with different arguments to get various parts of the returned object, but this results in repetitive code.
Overview
Python has a powerful technique called tuple unpacking where the tuple of values is unpacked into the variable names.
(fc_name,fc_type,sr) = ("Roads", "Polyline", 3006)
print(fc_name)
print(fc_type)
print(sr)
Roads
Polyline
3006
This can be handy when retrieving long sequences with values such as rows of a database table and you need to get only specific fields:
row = (2467, 998, 6, 0, u'dirt', u'SSteadman', 20021205, u'Beaver',
(331841.0650, 4129735.250))
ID,road_surface,rest = row[0],row[4],row[5:]
print "ID:",ID
print "Road surface:",road_surface
print "Garbage:",rest
ID: 2467
Road surface: dirt
Garbage: (u'SSteadman', 20021205, u'Beaver', (331841.065, 4129735.25))
Pure Python example of tuple unpacking
Before getting into arcpy
functions and tuple unpacking, let's go through a simpler example. Let's create a function that will let do some arithmetic operations on demand:
def do_calc(x, y, operation):
if operation == "+":
return x + y
if operation == "-":
return x - y
print do_calc(x=3, y=4, operation='+')
print do_calc(x=3, y=4, operation='-')
7
-1
Arguments are stored in a tuple:
input_args = (5, 8, '+')
#instead of accessing individual items within a tuple and matching the arguments order
print do_calc(x=input_args[0],y=input_args[1],operation=input_args[2])
#unpacking tuple, so every item in the tuple gets assigned to an input argument in order
print do_calc(*input_args)
Tuple unpacking for arcpy
operations
Here is another example of unpacking a sequence into arguments when constructing arcpy.Point
objects from a list of coordinates:
import arcpy
coords_pairs = [[14.45, 25.65, 567],
[24.23, 46.56, 580],
[34.89, 74.23, 593]]
#input data for Point ({X}, {Y}, {Z})
#instead of [arcpy.Point(c[0],c[1],c[2]) for c in coords_pairs]
points = [arcpy.Point(*coords) for coords in coords_pairs]
print(points)
[<Point (14.45, 25.65, 567.0, #)>,
<Point (24.23, 46.56, 580.0, #)>,
<Point (34.89, 74.23, 593.0, #)>]
Advanced use of tuple unpacking for arcpy
Unpacking tuples can be a very efficient technique when working with functions that can accept iterables of arbitrary length. Let's build a workflow that would let us add multiple fields to a feature class without writing arcpy.AddField_management()
line for every field.
import arcpy
input_fc = 'cities'
#(name,type,{precision},{scale},{length},{alias},{is_nullable},{is_required},{domain})
fields = [("ref_ID","LONG",9,"","","refcode","NULLABLE","NON_REQUIRED"),
("DataSet_ID","LONG",5,"","","datacode","NULLABLE","NON_REQUIRED"),
("Recomment","TEXT","","","35","recordcomment","NULLABLE","NON_REQUIRED")]
#adding each field in the list unpacking the tuple
for field_tuple in fields:
arcpy.AddField_management(*(input_fc,) + field_tuple)
There is another post on GIS.SE showing use of tuple unpacking for adding fields, helpful to review.