2

I want to clean this code in such a way that there are not so many for loops. For loops in the following code are placed to trap FCs in multiple group layers and do some work on them. My Data in TOC looks like this

Data (Main Group Layer)
--->Sub Group (First Sub Group)
----->FCs (in First Sub Group)
--->Sub Group 2 (Second Sub Group)
----->FCs (in Second Sub Group)
............

Although the code works fine Just wondering if we can make it more sleek.

Can you update it if there is room for improvement?

import arcpy
import fileinput
proj = arcpy.mp.ArcGISProject('CURRENT')  
#m = proj.listMaps()[0]  
m = proj.activeMap  
ml = m.listLayers("Data")                           # First Group Layer
for gl in ml:
    if gl.isGroupLayer:                             # Check if its Group Layer     
        arcpy.AddMessage("-"+gl.name+"-")
        mml = gl.listLayers()
        for sgl in mml:
            if sgl.isGroupLayer:                    # Check if its Sub Group Layer
                arcpy.AddMessage("--"+sgl.name+"--")
                lyrs = sgl.listLayers()
                for lyr in lyrs:
                    arcpy.AddMessage(lyr.name)
                    with arcpy.da.SearchCursor(lyr,['Assetic_ID','FL_ID']) as cur:   
                        for rows in cur:
                            with open("C:\\test\\file.csv", 'a') as f:                                
                                f.write('{0},{1}\n'.format(rows[0],rows[1]))
                                #print (rows, file =f)
arcpy.AddMessage("Finished")
2
  • 2
    For code review there is the Code Review Stack Exchange.
    – PolyGeo
    Nov 26, 2021 at 3:55
  • 1
    It looks like you don't need the exact structure with grouplayers and all, so you could just call ListLayers once, because it already returns all layers, including nested ones.
    – Berend
    Nov 26, 2021 at 8:17

1 Answer 1

5

I've put some comments inline, but the main one is - don't keep reopening a file for appending, just do it once. You might also want to consider using more descriptive variable names.

import arcpy
import fileinput                                     # unused import
proj = arcpy.mp.ArcGISProject('CURRENT')
m = proj.activeMap

with open("C:\\test\\file.csv", 'a') as f:           # Don't keep re-opening...

    ml = m.listLayers("Data")  # First Group Layer
    for gl in ml:
        if not gl.isGroupLayer:                      # Check if its Group Layer
            continue                                 # remove a level of indentation below
        arcpy.AddMessage(f"-{gl.name}-")             # string con+cat+enat+ion is bad, f"strings" are good

        for sgl in gl.listLayers():                  # no need for 2 lines to create a var then use it
            if not sgl.isGroupLayer:                 # Check if its Sub Group Layer
                continue                             # remove a level of indentation below
            arcpy.AddMessage(f"--{sgl.name}--")      # string con+cat+enat+ion is bad, f"strings" are good
    
            for lyr in sgl.listLayers():             # no need for 2 lines to create a var then use it
                arcpy.AddMessage(lyr.name)
                with arcpy.da.SearchCursor(lyr, ['Assetic_ID', 'FL_ID']) as cur:  
                    for rows in cur:
                        f.write(f'{rows[0]},{rows[1]}\n')  #  string.format is fine, but f"strings" are easier to read
                        
arcpy.AddMessage("Finished")

Since you are looking to reduce loops, here's an example that just loops through layers in a single loop:

import arcpy

proj = arcpy.mp.ArcGISProject('CURRENT')
m = proj.activeMap

data = m.listLayers('Data')[0]
for layer in data.listLayers():
    print(layer.longName)

enter image description here

0

Your Answer

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

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