You linked to a ArcGIS Pro help page (Python 3.6+) but you use a Python 2.7 print
command. The code below is written in Python 3.6+.
In case you are using Python 2.7 with ArcGIS for Desktop which I don't have, you should still be able to run the scripts below but need to change the print
command. See What's new in Python 3.0. The rest should be interchangeable but I did not test it.
You have a few issues in your code:
os.path.join(f, inputDirectory)
should be os.path.join(inputDirectory, f)
.
- You need to use
desc.dataType
to retrieve the data type and desc.file
for the file name.
- If the data type is not already in the dictionary, you'll need to assign a list, and not assigning the
desc
object.
import os
import arcpy
inputDirectory = "D:\projects\playground\python\stackgis\data" # simulating input
files = os.listdir(inputDirectory)
fDictionary = {}
for f in files:
desc = arcpy.Describe(os.path.join(inputDirectory, f))
if desc.dataType not in fDictionary:
fDictionary[desc.dataType] = [desc.file]
else:
fDictionary[desc.dataType].append(desc.file)
print('fDictionary {0}'.format(fDictionary))
Output:
fDictionary {'ShapeFile': ['a.dbf', 'a.shp', 'b.dbf', 'b.shp'], 'File': ['a.prj', 'a.shx', 'b.prj', 'b.shx'], 'RasterDataset': ['c.jpg', 'd.jpg']}
In addition, if you only want to process datasets, you may want to consider using arcpy.da.Walk
(but also iterates through sub directories) or arcpy.ListFeatureClasses
(requires arcpy.env.workspace
to be set) to iterate over the datasets. The example below uses arcpy.da.Walk
:
import os
import arcpy
inputDirectory = "D:\projects\playground\python\stackgis\data" # simulating input
fDictionary = {}
for root, _, datasets in arcpy.da.Walk(inputDirectory):
for dataset in datasets:
desc = arcpy.Describe(os.path.join(root, dataset))
if desc.dataType not in fDictionary:
fDictionary[desc.dataType] = [desc.file]
else:
fDictionary[desc.dataType].append(desc.file)
print('fDictionary {0}'.format(fDictionary))
Output:
fDictionary {'ShapeFile': ['a.shp', 'b.shp'], 'RasterDataset': ['c.jpg', 'd.jpg']}
You could use defaultdict
to make your code simpler:
import os
import arcpy
from collections import defaultdict
input_folder = "D:\projects\playground\python\stackgis\data" # simulating input
output = defaultdict(list)
for root, _, datasets in arcpy.da.Walk(input_folder):
for dataset in datasets:
desc = arcpy.Describe(os.path.join(root, dataset))
output[desc.dataType].append(desc.file)
print(f"Output {output}")
Output:
Output {'ShapeFile': ['a.shp', 'b.shp'], 'RasterDataset': ['c.jpg', 'd.jpg']}
Addendum: According to Vince's comment you may be looking to get the dataType
and file
properties dynamically from the Describe
object. There would be no need to do that. Both properties are always present in any Describe
object.
All data, regardless of the data type, will always acquire the generic Describe Object properties.
https://pro.arcgis.com/en/pro-app/latest/arcpy/functions/describe.htm
However, it makes sense to check for properties which are not available for all data types. See Vince's comments where he suggest hasattr
and getattr
.
Here is an example with the property extent
which is not be available for all data types:
desc = arcpy.Describe(r"d:\data\a.shp")
if hasattr(desc, "extent"):
extent = getattr(desc, "extent")
However, you are accessing only generic properties. Therefore is no need using hasattr
and getattr
.
hasattr
andgetattr
built-in functions of Python to dynamically explore the properties of ageoprocessing describe data object