48

I'm trying to perform some geoprocessing. My task is to locate all shapefiles within a directory, and then find the full path name for that shapefile within the directory. I can get the name of the shapefile, but I don't know how to get the full path name for that shapefile.

shpfiles = [] for path, subdirs, files in os.walk(path): for x in files: if x.endswith(".shp") == True: shpfiles.append[x] 
1
  • Side note the code if x.endswith(".shp") == True is not needed because a condition automatically checks if something is true. Instead you can change it to if x.endswith(".shp") Commented Dec 17, 2024 at 2:48

3 Answers 3

109

os.walk gives you the path to the directory as the first value in the loop, just use os.path.join() to create full filename:

shpfiles = [] for dirpath, subdirs, files in os.walk(path): for x in files: if x.endswith(".shp"): shpfiles.append(os.path.join(dirpath, x)) 

I renamed path in the loop to dirpath to not conflict with the path variable you already were passing to os.walk().

Note that you do not need to test if the result of .endswith() == True; if already does that for you, the == True part is entirely redundant.

You can use .extend() and a generator expression to make the above code a little more compact:

shpfiles = [] for dirpath, subdirs, files in os.walk(path): shpfiles.extend(os.path.join(dirpath, x) for x in files if x.endswith(".shp")) 

or even as one list comprehension:

shpfiles = [os.path.join(d, x) for d, dirs, files in os.walk(path) for x in files if x.endswith(".shp")] 
Sign up to request clarification or add additional context in comments.

1 Comment

Just a small addition to the answer. The file tail could be capitalized, eg.: test.jpg or test.JPG, which would return False in the statement if x.endswith(".jpg"):. We could use the Python built-in function str.lower() to prevent possible False s. With if x.lower().endswith(".jpg"): we lower the string before the comparison. Thereby, test.jpg and test.JPG will return True.
2

Why not import glob ?

import glob print(glob.glob('F:\OTHERS\PHOTOS\Panama\\mai13*\\*.jpg') ) 

and i get all the jpeg i want, with absolute path

>>> ['F:\\OTHERS\\PHOTOS\\Panama\\mai13\\03052013271.jpg', 'F:\\OTHERS\\PHOTOS\\Panama\\mai13\\05052013272.jpg', 'F:\\OTHERS\\PHOTOS\\Panama\\mai13\\05052013273.jpg'] 

3 Comments

glob() only supports a fixed depth of subdirectories, os.walk() supports arbitrary depths. See How can I search sub-folders using glob.glob module in Python?
Original question could be interpreted as a single directory. For those reading this answer who don't require subdirectories (like me), glob is more pythonic because it is more concise and yields a more immediately useful result.
after 8 years these replies are no longer valid. Glob now supports recursion.
0

Seems os.path.abspath(finename) will work. Please try.

shpfiles = [] for path, subdirs, files in os.walk(path): for x in files: if x.endswith(".shp") == True: shpfiles.append(os.path.join(path, x)) 

1 Comment

No it won't. abspath will base the filename of the current working directory, which can be a totally different path altogether.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.