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 Answer 1
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.
-
do you mean change name = arcpy.mapping.ListLayers(mxd, df).nameRachel– Rachel2018年12月05日 23:12:16 +00:00Commented Dec 5, 2018 at 23:12
-
1You probably want to address the iteration of a singleton and
x
reinitializationVince– Vince2018年12月05日 23:22:18 +00:00Commented 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.Michael Stimson– Michael Stimson2018年12月05日 23:42:09 +00:00Commented Dec 5, 2018 at 23:42
df
to the first element of a list, then try to iterate on the single element. 2) You reinitialize thex
variable to zero with each iteration of the loop. Also, the canonical form of "increment x by one" isx += 1