322

How do I count only the files in a directory? This counts the directory itself as a file:

len(glob.glob('*'))
Mateen Ulhaq
  • 21,459
  • 16
  • 82
  • 123
prosseek
  • 169,389
  • 197
  • 542
  • 840
  • To leave out directories, you can do '*.fileextension' for whatever file extension you are looking for. –  Mar 24 '18 at 02:28

28 Answers28

379

os.listdir() will be slightly more efficient than using glob.glob. To test if a filename is an ordinary file (and not a directory or other entity), use os.path.isfile():

import os, os.path

# simple version for working with CWD
print len([name for name in os.listdir('.') if os.path.isfile(name)])

# path joining version for other paths
DIR = '/tmp'
print len([name for name in os.listdir(DIR) if os.path.isfile(os.path.join(DIR, name))])
Bruno Bronosky
  • 60,791
  • 11
  • 147
  • 135
Daniel Stutzbach
  • 70,140
  • 17
  • 84
  • 76
  • 15
    Remember to add the `folder_path` inside `os.path.filename(name)` if you're not on the cwd. http://stackoverflow.com/questions/17893542/why-do-os-path-isfile-return-false – Rafael Oliveira Apr 10 '14 at 14:54
  • 1
    This doesn't count the file inside nested folders. – codersofthedark Apr 23 '15 at 09:33
  • 6
    For recursively counting files nested inside directories, you might be better off with the os.walk() solution. – Joel B Dec 23 '15 at 21:23
  • 3
    What is the benefit of using `os.path.join(DIR, name)` over `DIR + '/' + name`? The latter is shorter and, IMO, more clear than the former. Is there perhaps some OS:es on which the latter would fail? – HelloGoodbye Jun 16 '16 at 13:46
  • 2
    @HelloGoodbye That's exactly the reason. – ellockie Nov 29 '16 at 16:28
  • Doing this on a directory with a huge number of files is slow. Is there a way of getting the count in any other way? – Eduardo Pignatelli Apr 13 '18 at 16:17
  • If you need to search for a specific filename, then you can use `'your_filename' in name` like this: `print len([name for name in os.listdir('.') if os.path.isfile(name) and 'your_filename' in name])` – tsveti_iko Aug 10 '18 at 10:01
  • @HelloGoodbye if prettifying bugs you too much - `pathlib`'s (Pure)Path actually has `/` **operator** which does the same OS-aware stuff - `p / 'some' / 'dir'` https://docs.python.org/3/library/pathlib.html#operators – jave.web Nov 13 '20 at 01:28
  • Is this a disk intensive operation to run on unix? I am trying to create a directory serving API and for the UI, I wanna show count of subfolders/files but dont want to wear out the disk too much. – ScipioAfricanus Dec 20 '20 at 18:50
  • 7
    For those who uses python3, print(len(os.listdir('DIRECTORY_PATH'))) – Brady Huang Jan 08 '21 at 03:31
157
import os

_, _, files = next(os.walk("/usr/lib"))
file_count = len(files)
bryant1410
  • 4,712
  • 3
  • 36
  • 37
Luke
  • 1,772
  • 1
  • 10
  • 5
68

For all kind of files, subdirectories included:

import os

list = os.listdir(dir) # dir is your directory path
number_files = len(list)
print number_files

Only files (avoiding subdirectories):

import os

onlyfiles = next(os.walk(dir))[2] #dir is your directory path as string
print len(onlyfiles)
Guillermo Pereira
  • 1,659
  • 11
  • 7
47

This is where fnmatch comes very handy:

import fnmatch

print len(fnmatch.filter(os.listdir(dirpath), '*.txt'))

More details: http://docs.python.org/2/library/fnmatch.html

ngeek
  • 7,453
  • 11
  • 35
  • 42
  • 4
    This is much faster (about half the time with my testing on a directory with 10,000 files) if you know the pattern you're looking for, rather then testing each file with `os.path.isfile()` as the accepted answer does. Also significantly faster than `glob.glob()`. – CivFan Apr 27 '16 at 15:54
30

If you want to count all files in the directory - including files in subdirectories, the most pythonic way is:

import os

file_count = sum(len(files) for _, _, files in os.walk(r'C:\Dropbox'))
print(file_count)

We use sum that is faster than explicitly adding the file counts (timings pending)

Mr_and_Mrs_D
  • 29,590
  • 35
  • 170
  • 347
  • 1
    Hi, I was trying to understand this code (the code works perfect), I know we can use `_` in a `for` loop. `os.walk` also I know. But not sure what's going on with underscores inside the `sum` function, could you please elaborate. Thanks! – Ejaz Jan 02 '18 at 13:22
  • 1
    Unsderscore is just a variable name @Ejaz, by convention used when we ignore the variable - that's what we do here - we call walk and only count the number of files in each directory, ignoring the root and dirs walk return values – Mr_and_Mrs_D Jan 03 '18 at 18:58
  • 3
    This is completely recursive and probably the best answer here. – SomJura Sep 22 '20 at 21:25
  • 1
    This should be the most appropriate answer, to also count the files in any subfolders.. – NoobCat Oct 13 '20 at 13:54
15

I am surprised that nobody mentioned os.scandir:

def count_files(dir):
    return len([1 for x in list(os.scandir(dir)) if x.is_file()])
qed
  • 21,094
  • 18
  • 110
  • 180
14

Short and simple

import os
directory_path = '/home/xyz/'
No_of_files = len(os.listdir(directory_path))
13
import os
print len(os.listdir(os.getcwd()))
rash
  • 1,298
  • 1
  • 12
  • 16
12
def directory(path,extension):
  list_dir = []
  list_dir = os.listdir(path)
  count = 0
  for file in list_dir:
    if file.endswith(extension): # eg: '.txt'
      count += 1
  return count
Marcus Riemer
  • 6,579
  • 7
  • 52
  • 70
ninjrok
  • 170
  • 1
  • 8
9

An answer with pathlib and without loading the whole list to memory:

from pathlib import Path

path = Path('.')

print(sum(1 for _ in path.glob('*')))  # Files and folders, not recursive
print(sum(1 for _ in path.glob('**/*')))  # Files and folders, recursive

print(sum(1 for x in path.glob('*') if x.is_file()))  # Only files, not recursive
print(sum(1 for x in path.glob('**/*') if x.is_file()))  # Only files, recursive
Paul
  • 4,856
  • 2
  • 30
  • 61
8

This uses os.listdir and works for any directory:

import os
directory = 'mydirpath'

number_of_files = len([item for item in os.listdir(directory) if os.path.isfile(os.path.join(directory, item))])

this can be simplified with a generator and made a little bit faster with:

import os
isfile = os.path.isfile
join = os.path.join

directory = 'mydirpath'
number_of_files = sum(1 for item in os.listdir(directory) if isfile(join(directory, item)))
joaquin
  • 78,380
  • 27
  • 136
  • 151
8

While I agree with the answer provided by @DanielStutzbach: os.listdir() will be slightly more efficient than using glob.glob.

However, an extra precision, if you do want to count the number of specific files in folder, you want to use len(glob.glob()). For instance if you were to count all the pdfs in a folder you want to use:

pdfCounter = len(glob.glob1(myPath,"*.pdf"))
LBes
  • 3,236
  • 1
  • 26
  • 57
6

This is an easy solution that counts the number of files in a directory containing sub-folders. It may come in handy:

import os
from pathlib import Path

def count_files(rootdir):
    '''counts the number of files in each subfolder in a directory'''
    for path in pathlib.Path(rootdir).iterdir():
        if path.is_dir():
            print("There are " + str(len([name for name in os.listdir(path) \
            if os.path.isfile(os.path.join(path, name))])) + " files in " + \
            str(path.name))
            
 
count_files(data_dir) # data_dir is the directory you want files counted.

You should get an output similar to this (with the placeholders changed, of course):

There are {number of files} files in {name of sub-folder1}
There are {number of files} files in {name of sub-folder2}
MLDev
  • 196
  • 3
  • 7
5
def count_em(valid_path):
   x = 0
   for root, dirs, files in os.walk(valid_path):
       for f in files:
            x = x+1
print "There are", x, "files in this directory."
return x

Taked from this post

Kristian Damian
  • 1,335
  • 3
  • 21
  • 43
4

Luke's code reformat.

import os

print len(os.walk('/usr/lib').next()[2])
okobaka
  • 528
  • 4
  • 8
4
import os

def count_files(in_directory):
    joiner= (in_directory + os.path.sep).__add__
    return sum(
        os.path.isfile(filename)
        for filename
        in map(joiner, os.listdir(in_directory))
    )

>>> count_files("/usr/lib")
1797
>>> len(os.listdir("/usr/lib"))
2049
tzot
  • 87,612
  • 28
  • 135
  • 198
4

Here is a simple one-line command that I found useful:

print int(os.popen("ls | wc -l").read())
  • Parsing the output of `ls` is generally frowned upon (it can frequently cause issues), though this is not a bad "quick-and-dirty" method at the shell. You should use `ls -1`, though, so it guarantees one line per file. – Bloodgain Apr 03 '20 at 22:45
3

one liner and recursive:

def count_files(path):
    return sum([len(files) for _, _, files in os.walk(path)])

count_files('path/to/dir')
juan Isaza
  • 3,123
  • 2
  • 28
  • 36
2

I used glob.iglob for a directory structure similar to

data
└───train
│   └───subfolder1
│   |   │   file111.png
│   |   │   file112.png
│   |   │   ...
│   |
│   └───subfolder2
│       │   file121.png
│       │   file122.png
│       │   ...
└───test
    │   file221.png
    │   file222.png

Both of the following options return 4 (as expected, i.e. does not count the subfolders themselves)

  • len(list(glob.iglob("data/train/*/*.png", recursive=True)))
  • sum(1 for i in glob.iglob("data/train/*/*.png"))
user799188
  • 13,097
  • 3
  • 31
  • 36
2

It is simple:

print(len([iq for iq in os.scandir('PATH')]))

it simply counts number of files in directory , i have used list comprehension technique to iterate through specific directory returning all files in return . "len(returned list)" returns number of files.

Agha Saad
  • 31
  • 2
  • 1
    Welcome to Stack Overflow. The quality of this answer can be improved by adding an explanation: [How to Answer](https://stackoverflow.com/help/how-to-answer) – Elletlar Jul 29 '18 at 10:44
  • 1
    Thankyou Elletlar , i have edited my answer , i will make sure to respond in more comprehensive manner :D – Agha Saad Jul 31 '18 at 15:05
1
import os

total_con=os.listdir('<directory path>')

files=[]

for f_n in total_con:
   if os.path.isfile(f_n):
     files.append(f_n)


print len(files)
Mohit Dabas
  • 2,283
  • 1
  • 16
  • 12
1

If you'll be using the standard shell of the operating system, you can get the result much faster rather than using pure pythonic way.

Example for Windows:

import os
import subprocess

def get_num_files(path):
    cmd = 'DIR \"%s\" /A-D /B /S | FIND /C /V ""' % path
    return int(subprocess.check_output(cmd, shell=True))
styler
  • 11
  • 1
1

I found another answer which may be correct as accepted answer.

for root, dirs, files in os.walk(input_path):    
for name in files:
    if os.path.splitext(name)[1] == '.TXT' or os.path.splitext(name)[1] == '.txt':
        datafiles.append(os.path.join(root,name)) 


print len(files) 
Ismail
  • 39
  • 6
1

Simpler one:

import os
number_of_files = len(os.listdir(directory))
print(number_of_files)
Mayur Gupta
  • 243
  • 2
  • 14
0

i did this and this returned the number of files in the folder(Attack_Data)...this works fine.

import os
def fcount(path):
    #Counts the number of files in a directory
    count = 0
    for f in os.listdir(path):
        if os.path.isfile(os.path.join(path, f)):
            count += 1

    return count
path = r"C:\Users\EE EKORO\Desktop\Attack_Data" #Read files in folder
print (fcount(path))
jkalden
  • 1,479
  • 4
  • 23
  • 25
0

I solved this problem while calculating the number of files in a google drive directory through Google Colab by directing myself into the directory folder by

import os                                                                                                
%cd /content/drive/My Drive/  
print(len([x for x in os.listdir('folder_name/']))  

Normal user can try

 import os                                                                                                     
 cd Desktop/Maheep/                                                     
 print(len([x for x in os.listdir('folder_name/']))  
Maheep
  • 479
  • 6
  • 5
0

A simple utility function I wrote that makes use of os.scandir() instead of os.listdir().

import os 

def count_files_in_dir(path: str) -> int:
    file_entries = [entry for entry in os.scandir(path) if entry.is_file()]

    return len(file_entries)

The main benefit is that, the need for os.path.is_file() is eliminated and replaced with os.DirEntry instance's is_file() which also removes the need for os.path.join(DIR, file_name) as shown in other answers.

Kinyugo
  • 369
  • 2
  • 11
0

Convert to list after that you can Len

len(list(glob.glob('*')))

Eslamspot
  • 79
  • 5