7

What does *coords in the following code mean?

import arcpy


feature_info = [[[1, 2], [2, 4], [3, 7]],
                [[6, 8], [5, 7], [7, 2], [9, 5]]]


features = []

for feature in feature_info:
     Create a Polyline object based on the array of points
     Append to the list of Polyline objects
     features.append(
         arcpy.Polyline(
             arcpy.Array([arcpy.Point(*coords) for coords in feature])))


arcpy.CopyFeatures_management(features, "c:/geometry/polylines.shp")
  • is this the ESRI documentation? in my opinion its better to go with an insert cursor than to use this method of storing the coords in a list and using the copy features tool – ziggy Jul 13 '17 at 15:26
  • Welcome. See: gis.stackexchange.com/help/someone-answers. – Andre Silva Aug 15 '17 at 0:51
14

See Unpacking Argument Lists. Input for the Point object is for example X coordinate and Y coordinate as doubles:

point = arcpy.Point(1, 2)

In your example coords will be a list, like [1, 2]. This is unpacked with * into 1, 2

| improve this answer | |
6

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.

| improve this answer | |

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.