2
\$\begingroup\$

My script goes through sub folders in my main directory and based on a wildcard checks if a tiff file exists or not, if it exists then the file path is appended to the corresponding list. For example, all the tiff files with "*CRP.tif" wildcard, in all the sub folders, go into CRP_List = []. My current code is partially hard-coded, is there a way to make my code more generic? The individual lists i.e. the tiff path names are inputs to a raster mosaic tool which merges all the tiffs/rasters together..

import arcpy, os

#Raster Lists 
CRP_List = []
FOR_List = []
INR_List = []
IR_List = []
MO_List = []
PAS_List = []
TCI_List = []
TCT_List = []
TG_List = []
WAT_List = []
WLF_List = []
WLO_List = []
WLT_List = []

arcpy.env.workspace = "D:/A__P6_FINAL_TIFFs"

for folder in arcpy.ListWorkspaces("*"):
    folder_basename = os.path.basename(folder)
    CoName = folder_basename.rsplit('_',1)[0]
    env.workspace = os.path.join("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL")

    for raster in arcpy.ListRasters("*_CRP.tif"):
        if arcpy.Exists(raster):
            CRP_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*FOR.tif"):
        if arcpy.Exists(raster):
            FOREST_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_INR.tif"):
        if arcpy.Exists(raster):
            INR_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_IR.tif"):
        if arcpy.Exists(raster):
            IR_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_MO.tif"):
        if arcpy.Exists(raster):
            MO_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_PAS.tif"):
        if arcpy.Exists(raster):
            PAS_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_TCI.tif"):
        if arcpy.Exists(raster):
            TCI_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_TCT.tif"):
        if arcpy.Exists(raster):
            TCT_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_TG.tif"):
        if arcpy.Exists(raster):
            TG_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_WAT.tif"):
        if arcpy.Exists(raster):
            WAT_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_WLF.tif"):
        if arcpy.Exists(raster):
            WLF_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_WLO.tif"):
        if arcpy.Exists(raster):
            WLO_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

    for raster in arcpy.ListRasters("*_WLT.tif"):
        if arcpy.Exists(raster):
            WLT_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Could you update the post to explain why you need to do this? What do you plan to do with these TIFFs? \$\endgroup\$ Jan 12, 2017 at 20:15

1 Answer 1

4
\$\begingroup\$

You want to learn what a dictionary is, and store your rasters in it. With Python this is pretty simple, to make a dictionary that when you ask for an apple gives you a 'red apple' you could do:

>>> my_dictionary = {'apple': 'red apple'}
>>> my_dictionary['apple']
'red apple'

From this you want to build this dictionary, to do this you can add a banana to the dictionary:

>>> my_dictionary['banana'] = 'for scale'
>>> my_dictionary['banana']
'for scale'
>>> my_dictionary
{'apple': 'red apple', 'banana': 'for scale'}

After this you want to merge all the for loops together. Using a dictionary like above, we can drastically reduce the amount of code.

rasters = {}
for name, file_ext in [('CRP', '_CRP'), ('FOR', 'FOR'), ...]:
    list = rasters[name] = []
    for raster in arcpy.ListRasters("*" + file_ext + ".tif"):
        if arcpy.Exists(raster):
            CRP_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

Since you also want this to work when you loop through arcpy.ListWorkspaces("*") you can use collections.defaultdict to allow you to remove the need to create a list for each file extension. This would change the above to:

rasters = defaultdict(list)
for name, file_ext in [('CRP', '_CRP'), ('FOR', 'FOR'), ...]:
    list = rasters[name]
    for raster in arcpy.ListRasters("*" + file_ext + ".tif"):
        if arcpy.Exists(raster):
            CRP_List.append("D:/A__P6_FINAL_TIFFs/" + CoName + "_FINAL/" + raster)

Going further, you can use arcpy.env.workspace or another constant variable rather than writing "D:/A__P6_FINAL_TIFFs/" three times, this as if you want to change it you would have to do it twice at the moment. I would use str.format to simplify the formatting, so when another person reads it it's not as hard to know what's happening. And finally I would normalize your variable names, pick either CoName or co_name, as it's hard knowing what your variable naming convention is. This can get you:

import arcpy
import os
from collections import defaultdict

WORKSPACE = "D:/A__P6_FINAL_TIFFs"
arcpy.env.workspace = WORKSPACE

rasters = defaultdict(list)
for folder in arcpy.ListWorkspaces("*"):
    co_name = os.path.basename(folder).rsplit('_', 1)[0]
    env.workspace = os.path.join("{}/{}_FINAL".format(WORKSPACE, co_name))

    for name, file_ext in [('CRP', '_CRP'), ('FOR', 'FOR'), ...]:
        list = rasters[name]
        for raster in arcpy.ListRasters("*{}.tif".format(file_ext)):
            if arcpy.Exists(raster):
                list.append("{}{}_Final/{}".format(WORKSPACE, co_name, raster)
\$\endgroup\$
7
  • \$\begingroup\$ And the way you have it now, you don't need the path.join at all. Or you write os.path.join(WORKSPACE, "{}_FINAL".format(co_name)) \$\endgroup\$
    – Graipher
    Jan 12, 2017 at 20:56
  • \$\begingroup\$ Apologies. I shared a very old script when I was getting started, it took me a while but I've switched to str.format as default formatting. Also, I did not share my latest attempt using zip with three different lists and a nested loop which failed. Let me try using dictionary with your suggested syntax. \$\endgroup\$
    – cptpython
    Jan 12, 2017 at 21:00
  • \$\begingroup\$ @Peilonrayz, I didn't realize it but the loop indent got lost during copying and pasting the code. The arcpy.ListWorkspaces()loop defines the work directory and then arcpy.ListRasters() finds the tiff files within those directories. I've tried playing around with your code but ultimately I end up with only last county's (CoName/co_name) information in there. \$\endgroup\$
    – cptpython
    Jan 12, 2017 at 21:44
  • \$\begingroup\$ @cptpython Should be fixed, :) \$\endgroup\$
    – Peilonrayz
    Jan 12, 2017 at 22:11
  • \$\begingroup\$ @Peilonrayz - I tried that indent prior to your edit and it works as far as looping through different workspaces, but something is getting lost here as far as appending names tiff path names to each list. After running the script, the dictionary and list only shows raster/tiff from the very last sub-dir. I will update the question with my current script. \$\endgroup\$
    – cptpython
    Jan 18, 2017 at 15:41

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.