I'm working on 24 MXD files. Several maps include "roads" layer in them, the other maps don't have this layer. I'm trying to add "roads" layer to all the maps that do not have this layer by using this code:

import arcpy,os,sys,fnmatch
from arcpy import env

env.workspace = r"G:\desktop\Project"
insertLayer = arcpy.mapping.Layer(r"G:\desktop\Project\layers\roads.lyr")
counter = 0 

for mxdname in arcpy.ListFiles("*.mxd"):
    print mxdname 
    mxd = arcpy.mapping.MapDocument(r"G:\desktop\Project\\" + mxdname)
    df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
    refLayer = arcpy.mapping.ListLayers(mxd, "residence", df)[0]
for lyr in arcpy.mapping.ListLayers(mxd, "" ,df):
    if 'roads' not in lyr:  
        arcpy.mapping.InsertLayer(df, refLayer, insertLayer, "BEFORE") # BEFORE\ AFTER
counter = counter + 1

del mxd 
print counter

and this is the error i get:

Traceback (most recent call last):
  File "G:/desktop/y/yaron/shonot/software/---gis---/tools/YARON_SCRIPTS/aaaaaaaaaaaaaaaaa.py", line 18, in <module>
if 'roads' not in lyr:
  File "C:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\arcobjects\mixins.py", line 361, in __iter__
AttributeError: LayerObject: Get attribute layers does not exist


I added this code line:

  if 'roads' not in lyr.name:

and now 'roads' layer has been added several times (each map) to all maps no matter if they contain 'roads' layer or not.

  • 3
    Maybe its just to text formatting in your question but shouldn't the second 'for' loop be inside the first?
    – Dowlers
    May 10, 2016 at 14:15
  • how do i do it?
    – newGIS
    May 11, 2016 at 6:22

2 Answers 2


Your variable lyr is a layer object and not a string or list of strings.

Consequently, to avoid that error you need to replace:

if 'roads' not in lyr:


if 'roads' not in lyr.name:
  • now, 'roads' layer add 4 times to all the maps
    – newGIS
    May 10, 2016 at 12:27

Rather than looping through the layers, you can use python's filter function to determine if the roads layer is present.

So, replace

for lyr in arcpy.mapping.ListLayers(mxd, "" ,df):
if 'roads' not in lyr:  
    arcpy.mapping.InsertLayer(df, refLayer, insertLayer, "BEFORE") # BEFORE\ AFTER


if not filter(lambda x: 'roads' in x.name, arcpy.mapping.ListLayers(mxd, "" ,df)):  
    arcpy.mapping.InsertLayer(df, refLayer, insertLayer, "BEFORE") # BEFORE\ AFTER

Update: If you don't want to use lambdas, you can set a flag in the loop then insert the layer afterwards

has_roads = False
for lyr in arcpy.mapping.ListLayers(mxd, "" ,df):
    if 'roads' in lyr.name:
        has_roads = True
if not has_roads:
    arcpy.mapping.InsertLayer(df, refLayer, insertLayer, "BEFORE") # BEFORE\ AFTER
  • jon_two i didn't understand your code but it works, thanks. I would like to know if i can do it with my code , without lambda, is there another way?, is it possible?
    – newGIS
    May 11, 2016 at 6:02
  • Filter [docs.python.org/2/library/functions.html#filter] returns an array of everything that matches the function in the first argument. The lambda here goes through everything in the second argument, checking the name property.
    – jon_two
    May 11, 2016 at 8:26
  • Yes, I was just thinking this morning that you can use a boolean flag to show the road layer is present. See edit above.
    – jon_two
    May 11, 2016 at 8:30
  • thanks jon_two-the code works exect i added change: "if 'roads' in lyr.name:" as PolyGeo said
    – newGIS
    May 15, 2016 at 6:52
  • 1
    @newGIS oops, you're right. Corrected it now.
    – jon_two
    May 16, 2016 at 10:02

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.