List only files in a directory?

Question:

Is there a way to list the files (not directories) in a directory with Python? I know I could use os.listdir and a loop of os.path.isfile()s, but if there’s something simpler (like a function os.path.listfilesindir or something), it would probably be better.

Asked By: tkbx

||

Answers:

This is a simple generator expression:

files = (file for file in os.listdir(path) 
         if os.path.isfile(os.path.join(path, file)))
for file in files: # You could shorten this to one line, but it runs on a bit.
    ...

Or you could make a generator function if it suited you better:

def files(path):
    for file in os.listdir(path):
        if os.path.isfile(os.path.join(path, file)):
            yield file

Then simply:

for file in files(path):
    ...
Answered By: Gareth Latty

You could try pathlib, which has a lot of other useful stuff too.

Pathlib is an object-oriented library for interacting with filesystem paths. To get the files in the current directory, one can do:

from pathlib import *
files = (x for x in Path(".") if x.is_file())
for file in files:
    print(str(file), "is a file!")

This is, in my opinion, more Pythonic than using os.path.

See also: PEP 428.

Answered By: riamse

Using pathlib in Windows as follow:

files = (x for x in Path(“your_path”) if x.is_file())

Generates error:

TypeError: ‘WindowsPath’ object is not iterable

You should rather use Path.iterdir()

filePath = Path("your_path")
if filePath.is_dir():
    files = list(x for x in filePath.iterdir() if x.is_file())
Answered By: Noam Manos
files = next(os.walk('..'))[2]
Answered By: johnson

Using pathlib, the shortest way to list only files is:

[x for x in Path("your_path").iterdir() if x.is_file()]

with depth support if need be.

Answered By: mxdbld

For the special case of working with files in the current directory, you could do it as a simple one-liner list comprehension:

[f for f in os.listdir(os.curdir) if os.path.isfile(f)]

Otherwise in the more general case, directory paths & filenames have to be joined:

dirpath = '~/path_to_dir_of_interest'
files = [f for f in os.listdir(dirpath) if os.path.isfile(os.path.join(dirpath, f))]
Answered By: Neil

Since Python 3.6 you can use glob with a recursive option “**”. Note that glob will give you all files and directories, so you can keep only the ones that are files

files = glob.glob(join(in_path, "**/*"), recursive=True)
files = [f for f in files if os.path.isfile(f)]
Answered By: acaruci

If you use Python 3, you could use pathlib.

But, you have to know that if you use the is_dir() method as :

from pathlib import *

#p is directory path
#files is list of files in the form of path type

files=[x for x in p.iterdir() if x.is_file()]

empty files will be skipped by .iterdir()

The solution I found is:

from pathlib import *

#p is directory path

#listing all directory's content, even empty files
contents=list(p.glob("*"))

#if element in contents isn't a folder, it's a file
#is_dir() even works for empty folders...!

files=[x for x in contents if not x.is_dir()]
Answered By: PetitBrezhoneg
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.