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

3
  • do you mean change name = arcpy.mapping.ListLayers(mxd, df).name
    – Rachel
    Commented Dec 5, 2018 at 23:12
  • 1
    You probably want to address the iteration of a singleton and x reinitialization
    – Vince
    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

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

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