arcpy.mapping.ListLayoutElements List Index Out Of Range

256
2
01-07-2022 07:45 AM
Scott_Shenberger
New Contributor

I am taking over a script from someone who has since retired. This script is used to create pdf documents of quarter sections from a map series created by data driven pages (ArcGIS 10.7). On the pdf there are map notes (among others as you can see below) from a feature class called NoteFeatures. When I try to run this script I keep getting an List Index Out Of Range error. Im still somewhat of a novice at Python so I am not sure what I am missing.

import arcpy, os, sys

# Get the data driven pages object from your mxd
# You will use this to export your pages
mxd = arcpy.mapping.MapDocument(r"C:\Users\SShenbe1\Desktop\Project\VMPrinting4.mxd")
ddp = mxd.dataDrivenPages

# Get the layer you are using as an Index Layer
# In this case the layer is in the data frame "Layers" and called "TWGrid3"
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
gridLayer = arcpy.mapping.ListLayers(mxd, "TWGrid3", df)[0]

# Get the layer for the feature class used to indicate inset map locations
# This needs to be in the same data frame as your index layer
# In this case the layer is in the data frame "Layers" and called "DetCircles2"
# First, make a layer from the feature class "DetCircles2"
arcpy.env.workspace = "C:\Users\SShenbe1\Desktop\Project"
arcpy.MakeFeatureLayer_management("DetCircles2.shp", "Details_lyr")
detailCircles = "Details_lyr"

# Set the base values for the position of your first inset map
# Locations of all the inset maps will be calculated based on these values
baseXpos = 3.0
baseYpos = 12.9

# Create objects for the layout elements that will be moving, e.g., notes and abandonment elements

notes = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "NOTES")[0]
abandonments = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", "ABANDONMENTS")[0]
triangle = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", "TRIANGLE")[0]
diamond = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", "DIAMOND")[0]
noteTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "noteTitle")[0]
abandonmentTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "abandonmentTitle")[0]

.

.

.

.

.

.

.

0 Kudos
2 Replies
JeffK
by MVP Regular Contributor
MVP Regular Contributor

That means one of your lists is either empty, or the indexing ( the '[0]' ) is trying to reference an item that is more than what the list contains. So in one of these lines, the list is empty and the code cannot reference the index ([0])

df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
gridLayer = arcpy.mapping.ListLayers(mxd, "TWGrid3", df)[0]
notes = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "NOTES")[0]
abandonments = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", "ABANDONMENTS")[0]
triangle = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", "TRIANGLE")[0]
diamond = arcpy.mapping.ListLayoutElements(mxd, "GRAPHIC_ELEMENT", "DIAMOND")[0]
noteTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "noteTitle")[0]
abandonmentTitle = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "abandonmentTitle")[0]

 

think of it this way.  Python is a zero indexed language so a list of 5 items is indexed like:

alistof5Items = [0, 1, 2, 3, 4]

alistof5Items[5] will throw an index out of range error because it is trying to get the 6 item in the list, which there is none.

Step through your code with a debugger or add some print statements printing the length of the item to tell which list is empty.  Your error that you are getting now might even tell you which line is failing so check the error message in more detail.

JeffK
by MVP Regular Contributor
MVP Regular Contributor

You can add conditionals to check for empty lists too before assigning an index.

noteElements = arcpy.mapping.ListLayoutElements(mxd, "TEXT_ELEMENT", "noteTitle")
# One liner method
noteTitle = noteElements[0] if noteElements else ''

# -----
# Three liner method
noteTitle = ''
if noteElements: # check if not empty []
    noteTitle = noteElements[0]