4

I'm trying to add multiple fields to a table using arcpy and am wondering if it's possible to have multiple fields declared in the AddField management, and their values, separated by commas or something? Here is the code as stands, which is slightly cumbersome:

import arcpy, sys

arcpy.env.workspace = "C:\\gislab2\\Python\\take_home"
shapefile = "USCancer2000.shp"

#Set fieldname variables
field_name1 = "Crdrt"
field_name2 = "Crdrt_min"
field_name3 = "Crdrt_max"
field_name4 = "Ageadj"
field_name5 = "MinAgeAdj"
field_name6 = "MaxAgeAdj"

###Declare each standard population per age group, and for summed standard population
Pop1Stnd=78784000 
Pop2Stnd=150486000
Pop3Stnd=45364000
TotalStnd=274634000


    #Add the fields one at a time 
    arcpy.AddField_management(shapefile,field_name1,"DOUBLE",
"5","4","","","NULLABLE","NON_REQUIRED","")
    arcpy.AddField_management(shapefile,field_name2,"DOUBLE", "5","4","","","NULLABLE","NON_REQUIRED","")
    arcpy.AddField_management(shapefile,field_name3,"DOUBLE", "5","4","","","NULLABLE","NON_REQUIRED","")
    arcpy.AddField_management(shapefile,field_name4,"DOUBLE", "5","4","","","NULLABLE","NON_REQUIRED","")
    arcpy.AddField_management(shapefile,field_name5,"DOUBLE", "5","4","","","NULLABLE","NON_REQUIRED","")
    arcpy.AddField_management(shapefile,field_name6,"DOUBLE", "5","4","","","NULLABLE","NON_REQUIRED","")

I know there's a way to create a loop to do it, but was wondering if there was a simpler and more direct way.

4
  • 1
    This sounds like a homework question, but I would say that adding your fields in a loop is the most efficient way to go assuming your field types are all the same. Apr 7, 2013 at 19:00
  • 1
    self-edification, not homework.
    – David Meek
    Apr 7, 2013 at 22:42
  • 1
    The file paths from -all- of your posts suggest otherwise.
    – nagytech
    Apr 7, 2013 at 23:31
  • 1
    just because I'm in a class doesn't equate a question with homework.
    – David Meek
    Apr 8, 2013 at 0:02

6 Answers 6

9

A few techniques involved here. First off, I am storing all the arguments as tuples in a list. I can iterate through the list using a for-in loop. The tuples can be unpacked into function arguments using the * operator. I could have just gone with field names in a list, but then you would have not been able to be flexible in the other attributes of the field.

The shapefile, though, does stay constant throughout (and I assume that the name of the shapefile is stored in the variable shapefile as above). So, I do tuple concatenation inside the loop to build my entire set of arguments:

(shapefile,) + field

The trailing comma on shapefile, is necessary to tell the interpreter that you are creating a tuple with only one element. The end result is a tuple that can be unpacked with the * operator. As an example, the first tuple processed will be:

("USCancer2000.shp","Crdrt","DOUBLE","5","4","","","NULLABLE","NON_REQUIRED","")

Notice that tuple concatenation takes precedence over the * operator, so that the entire concatenated tuple is unpacked instead of just (shapefile,).

fields = [
    ("Crdrt","DOUBLE","5","4","","","NULLABLE","NON_REQUIRED",""),
    ("Crdrt_min","DOUBLE","5","4","","","NULLABLE","NON_REQUIRED",""),
    ("Crdrt_max","DOUBLE","5","4","","","NULLABLE","NON_REQUIRED",""),
    ("Ageadj","DOUBLE","5","4","","","NULLABLE","NON_REQUIRED",""),
    ("MinAgeAdj","DOUBLE","5","4","","","NULLABLE","NON_REQUIRED",""),
    ("MaxAgeAdj","DOUBLE","5","4","","","NULLABLE","NON_REQUIRED","")
]
for field in fields:
    arcpy.AddField_management(*(shapefile,) + field)

Edit: Revisiting this old answer to add a different technique to it, using partials. This is based on the specific question, where every field has the exact same parameters except field_name. If the parameters change from field to field, then try the tuples with * operator technique above instead.

import arcpy
from functools import partial

arcpy.env.workspace = "C:\\gislab2\\Python\\take_home"
shapefile = "USCancer2000.shp"

#List of fields to add, all with same type, precision, and scale
fields = ["Crdrt", "Crdrt_min", "Crdrt_max", "Ageadj", "MinAgeAdj", "MaxAgeAdj"]

#Since all arguments are the same except field_name, create partial
# that has default arguments for everything except field_name
addfield = partial(
    arcpy.AddField_management,
    shapefile,
    field_type="DOUBLE",
    field_precision=5,
    field_scale=4)
#Resulting partial function has field_name as first argument since in_table
# is already defined

#Now just loop through list of fields calling the partial function
for field in field:
    addfield(field)

The last call, addfield(field), is the equivalent of calling:
arcpy.AddField_management(shapefile, field, field_type="DOUBLE", field_precision=5, field_scale=4)
on each iteration of the loop. All the other parameters are the default parameters for arcpy.Addfield_management so we do not have to supply those.

1
  • A really useful answer, was trying to achieve this with dictionary first, but then recalled the tuples and saw your answer :) Sep 10, 2013 at 15:12
6

I usually use one-liner list comprehension for such cases:

[arcpy.AddField_management(shapefile,field_name,"DOUBLE", "5","4","","","NULLABLE","NON_REQUIRED","") for field_name in ['Crdrt', 'Crdrt_min', 'Crdrt_max', 'Ageadj', 'MinAgeAdj', 'MaxAgeAdj']]
3

You may want to consider not using Python at all on this one but the advice here can also be used within a Python script.

If you want to avoid multiple AddFields consider creating a single empty table with all those fields and then using Join Fields based on the OID field.

It should join them all in one go.

You could create your empty Table manually by creating your new Table in the Catalog window or use Create Table/Add Field(s) in a Python script.

2

I like Brett's original answer but as 99% of the time I only modify Field Name, Type and Length - use the following (can be adapted to expose more parameters if required).

# Define the field parameters
fields = [
          ("Point_Type","TEXT","50"),
          ("Point_Label","TEXT","50"),
          ("Created_By","TEXT","50"),
          ("Time_Created","Date",""),
          ("Created_PC","TEXT","50"),
          ("Last_Edit_By","TEXT","50"),
          ("Time_Last_Edit","Date",""),
          ("Last_Edit_PC","TEXT","50"),
          ("Comments","TEXT","255"),
          ("Record_Status","TEXT","50")
          ]

# Create the fields using the above parameters
for field in fields:
    arcpy.AddField_management(secc_maps_point, field[0], field[1], "", "",
                              field[2], "", "NON_NULLABLE", "NON_REQUIRED", "")
2

Since ArcGIS Pro 2.0, the AddFields tool was introduced. Note the "S"

From the help, an example of adding multiple fields all at once.

arcpy.management.AddFields(
    'school', 
    [['school_name', 'TEXT', 'Name', 255, 'Hello world', ''], 
     ['street_number', 'LONG', 'Street Number', None, 35, 'StreetNumDomain'],
     ['year_start', 'DATE', 'Year Start', None, '2017-08-09 16:05:07', '']])
0

I made a function that uses a list to add multiple fields at once which is below:

def MultipleAddFields(FeatureToAdd,Fields):
    for a,b,c in Fields:
        arcpy.AddField_management(FeatureToAdd,a,b,'','','',c)

The three inputs are Name, type, alias – but can add more if you want to. then just have to call function to use in script again.

fields_to_add[('Study_Area','TEXT','Study Area'),('Area','Double','Area')]
featureClass = r'path/to/feature...'

MultipleAddFields(featureClass,fields_to_add)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.