1

My ArcMap verison is 10.2.

My goal is to print the name of each layer in a mxd using Arcpy.

My script is below. There is no error, but it prints the first layer multiple times instead of all the layers in the "Main Map" data frame.

Does anyone have a solution?

import arcpy
mxd = arcpy.mapping.MapDocument(r"O:\Solar Databases\MO_projects.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "Main Map")[0]
for lyr in df:
 x = 0
 name = arcpy.mapping.ListLayers(mxd, "", df)[x].name
 print name
 x = x+1
del mxd
PolyGeo
65.5k29 gold badges115 silver badges349 bronze badges
asked Dec 5, 2018 at 22:42
1
  • 2
    You have two fundamental Python errors in this code. 1) You initialize df to the first element of a list, then try to iterate on the single element. 2) You reinitialize the x variable to zero with each iteration of the loop. Also, the canonical form of "increment x by one" is x += 1 Commented Dec 5, 2018 at 23:20

1 Answer 1

3

You need to use ListLayers to iterate the layers:

import arcpy
mxd = arcpy.mapping.MapDocument(r"O:\Solar Databases\OSER Solar\Projects\(MO) Berntie Land Status.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "Main Map")[0]
for lyr in arcpy.mapping.ListLayers(mxd, df): # List the layers in this data frame
 #x = 0 # if you set x=0 here then each iteration will start at 0 and finish at 1
 name = lyr.name
 print name
 #x = x+1 # the use of x is redundant
del mxd

Don't try to index the layer list directly, the order is arbitrary and not guaranteed to be in the same order in multiple calls. The direct indexing of ListDataFrames is acceptable provided there is only 1 data frame called "Main Map" - the order of 1 object, although arbitrary is still 1 object.

To work with layers by index you can do it this way:

import arcpy
mxd = arcpy.mapping.MapDocument(r"O:\Solar Databases\OSER Solar\Projects\(MO) Berntie Land Status.mxd")
df = arcpy.mapping.ListDataFrames(mxd, "Main Map")[0]
AllLayers = arcpy.mapping.ListLayers(mxd, df)
for x in range(len(AllLayers)):
 lyr = AllLayers[x] # layer from list by index
 name = lyr.name
 print name
del mxd

Using the range() function you create a list [0,1,2..n], where n is the number of items in the list minus 1 - remembering lists are 0 based (the first item is 0, the last is len(list)-1). Get your list of layers once and then access it many times, that way you can guarantee the order hasn't changed during an iteration.

answered Dec 5, 2018 at 22:52
3
  • do you mean change name = arcpy.mapping.ListLayers(mxd, df).name Commented Dec 5, 2018 at 23:12
  • 1
    You probably want to address the iteration of a singleton and x reinitialization Commented Dec 5, 2018 at 23:22
  • With the edit x is redundant. ListLayers returns a list so arcpy.mapping.ListLayers(mxd, df).name will return a type error, list has no attribute 'name'; the edit lists the layers once and then iterates the list in the variable lyr, which is a arcpy.mapping.Layer object which does have an attribute 'name'. Python has no for (int X = 0;X < Max;X++) loop so incrementing a counter and using an index on a list is not pythonic, to do this pythonically you would set AllLayers = arcpy.mapping.ListLayers(mxd, df) then for x in range(len(AllLayers)): and make lyr = AllLayers[x] - not relisting. Commented Dec 5, 2018 at 23:42

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.