I am trying to total the lengths of line segments. I know you can see this by right clicking field name and selecting summarize. How do I pass this value to a field via python.

Here is what I have tried.

expression = "sum(float(!SHAPE.length!))"

arcpy.CalculateField_management(in_table, field_name, expression, "PYTHON_9.3")

The error I receive tells me that the 'float object is not iterable'. Which tells me maybe I should be using a search cursor?

I have also tried this:

    expression = "getSum(float(!SHAPE.length!))"
    codeblock =  """def getSum(length):
        b = sum(row[0] for row in arcpy.da.SearchCursor(fc, 'length'))
        return b """
    arcpy.CalculateField_management(in_table, field_name, expression, 
        "PYTHON_9.3", codeblock)

But I get global fc not defined. How do I pass fc to codeblock.

What are my best options for performing this simple task?


Update: I found a solution using geometry objects. Reference here.

geometries = arcpy.CopyFeatures_management(fc, arcpy.Geometry())

# Walk through each geometry, totaling the length
length = sum([g.length for g in geometries])

# Execute CalculateField 
arcpy.CalculateField_management(in_table, field_name, length, "PYTHON_9.3")
  • 1
    Your mistake here is you are using the CalculateField. This is used to WRITE data into the field, you simply want to read it and total it up, so your use of a search cursor being called in a Calculate field tool is not making any sense. The question here is where are you wanting to put the total length? Are you wanting to simply display it or write it? Consider using the Summary Statistics tool, this creates a new table which could hold your values. – Hornbydd Apr 24 '17 at 16:41
  • @Hornbydd. This is being stored in the variable field_name. Its actually a field I intend to calculate a percentage of each line segment into once I can grab the sums. field_name = 'percentage'. I am using variable b as an object to hold the sum function. I'm still not sure whats wrong with this? – wtgeographer Apr 24 '17 at 18:44
  • I found this example using geometry objects. pro.arcgis.com/en/pro-app/arcpy/get-started/…. For code clarity I have added working solution to question. – wtgeographer Apr 24 '17 at 18:52

If you just want the percentage on each line, you're on the right track.

total = float(sum(row[0] for row in arcpy.da.SearchCursor(fc, 'SHAPE@LENGTH')))
with arcpy.da.UpdateCursor(fc, ('SHAPE@LENGTH', 'percent')) as uCursor:
    for length, percent in uCursor:
        uCursor.updateRow([length, length / total])

Cursors to access the length token should be a bit faster than copying the relatively heavy geometry object.

| improve this answer | |
  • I have adopted your answer. This answer populates my field fully as intended and processes quickly at that. I just added *100 to the update expression. ` uCursor.updateRow([length, (length / total)*100]) ` – wtgeographer Apr 25 '17 at 20:07

If you want to calculate total lenth of all line segments in your shape file you can try this:

import arcpy
fc= "your_shape_file.shp"
cursor= arcpy.da.SearchCursor(inFc, "SHAPE@")
for geom in cursor:
print total_length

I hope it will work.

| 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.