I think you just need to read the esri help file on ListLayers so you understand what it is actually being returned.
This is the link.
http://desktop.arcgis.com/en/desktop/latest/analyze/arcpy-mapping/listlayers.htm
In particular, note how the layers are listed and how you can use the longName property of the layers to determine which layers belong to a group (or not).
Input from Damijan
I have an empty group layer inside my map and I am looking for a way of initiating a process if there are 0 layers inside the group layer.
It appears you want to know whether a group layer is actually empty or contains layers or sub layers/groups.
Here is the code to accomplish this task:
mxd = arcpy.mapping.MapDocument("CURRENT")
df = arcpy.mapping.ListDataFrames(mxd)[0]
grpListSplit = []
grpListSplit2 = []
grpListSplitFinal = []
for grp in arcpy.mapping.ListLayers(mxd):
# if longName contains \\ it means that it is inside the group layer
if '\\' in grp.longName and (grp.isFeatureLayer or grp.isRasterLayer or grp.isNetworkAnalystLayer or grp.isRasterizingLayer or grp.isServiceLayer or grp.isGroupLayer):
# make sure to obtain the first item, that is group layer name from the longName
grpListSplit.append(grp.longName.split('\\')[0])
# if layer does not contain \\ in longName and it is a group layer it means that it is the top group layer - you exclude the sub-group layers
elif '\\' not in grp.longName and grp.isGroupLayer:
grpListSplit2.append(grp2.longName)
Taken from https://stackoverflow.com/questions/35713093/how-can-i-compare-two-lists-in-python-and-return-not-matches and slightly modified
def returnNotMatches(a, b):
return [x for x in b if x not in a]
grpListSplitFinal = returnNotMatches( grpListSplit,grpListSplit2 )
print grpListSplitFinal
And the result:
[u'Name', u'New Group Layer']
Now do something with the grpListSplitFinal. E.g remove those empty group layers
for grp in arcpy.mapping.ListLayers(mxd):
if grp.name in grpListSplitFinal:
if grp.isGroupLayer:
arcpy.mapping.RemoveLayer(df, grp)
Both Name and New Group Layers were actually empty group layers.
Some caveats:
- If you have more than one Group layer (an empty one and non-empty) with the same name (the main group layer not the sub-group layer) the comparison (returnNotMatches) will not work. This is because group layers name would appear in both lists. E.g. Group Layer has a name Cars and it is empty and we have another group layer with the same name containing layers and/or the sub-groups (with or without layers) then the same group layer name will appear in both lists (grpListSplit and grpListSplit2).
Possible solution:
Use something like
for i in grpListSplit:
print i + " : " + str(grpListSplit.count(i))
and then apply condition based on the count.
- If you are removing an empty Layer group and you have sub group layer with the same name under another group layer, this sub group layer will be also removed. E.g. Cars (an empty group layer) and Transport\Cars would be both removed.
Possible solution:
This could be probably solved by using indexes. Look here https://stackoverflow.com/questions/17133028/arcgis-python-index-of-layer-within-a-dataframe for the example.
- Also code as it is will work only on the first data frame.
Solution:
Expand code that will loop through data frames
for d in arcpy.mapping.ListDataFrames(mxd):
print d.name
Even better solution than above is to simply loop through all group layers as such:
mxd = arcpy.mapping.MapDocument("CURRENT")
cnt = 0
df = arcpy.mapping.ListDataFrames(mxd,'')[0]
listLayers = arcpy.mapping.ListLayers(mxd, '', df)
for lyr in listLayers:
if lyr.isGroupLayer:
for subGroup in lyr:
cnt += 1
if cnt == 0:
# To rename Group layer
lyr.name = lyr.name + "_EMPTY"
# To delete empty Group layer
arcpy.mapping.RemoveLayer(df, lyr)
cnt = 0
Layer
objects thatListLayers
gives you access to.