如何使用Python读取文件夹中的文件数量?

24

如何使用Python读取特定文件夹中的文件数量?提供示例代码会更好!

9个回答

33

如果你想非递归地计算文件和目录的数量,可以使用os.listdir 并获取其长度。

如果你想递归地计算文件和目录的数量,可以使用os.walk 来遍历目录中的文件和子目录。

如果你只想计算文件而不是目录的数量,可以使用 os.listdiros.path.isfile来检查每个条目是否为文件:

import os.path
path = '.'
num_files = len([f for f in os.listdir(path)
                if os.path.isfile(os.path.join(path, f))])

或者可以使用生成器:

num_files = sum(os.path.isfile(os.path.join(path, f)) for f in os.listdir(path))

或者您可以按照以下方式使用os.walk:

len(os.walk(path).next()[2])

我从这个帖子中获得了一些想法。


25

pathlib 是 Python 3.4 新增的模块,使得操作更加简单。标有 1 的这行代码可以生成当前文件夹下非递归的列表,而标有 2 的这行代码可以生成递归的列表。

from pathlib import Path

import os
os.chdir('c:/utilities')

print (len(list(Path('.').glob('*')))) ## 1
print (len(list(Path('.').glob('**/*')))) ## 2

还有更多好东西。使用这些额外的行,您可以看到文件名的绝对路径和相对路径,针对那些文件的项目。

for item in Path('.').glob('*'):
    if item.is_file():
        print (str(item), str(item.absolute()))

结果:

boxee.py c:\utilities\boxee.py
boxee_user_catalog.sqlite c:\utilities\boxee_user_catalog.sqlite
find RSS.py c:\utilities\find RSS.py
MyVideos34.sqlite c:\utilities\MyVideos34.sqlite
newsletter-1 c:\utilities\newsletter-1
notes.txt c:\utilities\notes.txt
README c:\utilities\README
saveHighlighted.ahk c:\utilities\saveHighlighted.ahk
saveHighlighted.ahk.bak c:\utilities\saveHighlighted.ahk.bak
temp.htm c:\utilities\temp.htm
to_csv.py c:\utilities\to_csv.py

1
使用 iterdir 的等效于 ## 1 行的代码是 print( len(list(Path('.').iterdir())) ) - jave.web

7
您可以使用 glob 模块:
>>> import glob
>>> print len(glob.glob('/tmp/*'))
10

或者,正如马克·拜尔斯在他的答案中建议的那样,如果你只想要文件:

>>> print [f for f in glob.glob('/tmp/*') if os.path.isfile(f)]
['/tmp/foo']
>>> print sum(os.path.isfile(f) for f in glob.glob('/tmp/*'))
1

应该说,os.listdir('.') 包括隐藏文件(以单个点开头),而 glob('./*') 则不包括。 - user355252
如果你想要当前目录下的隐藏文件,请使用 glob('.*')。如果你想要包括所有文件,包括隐藏文件,请使用 glob('.*') + glob('*') - bstpierre

6

马克·拜尔(Mark Byer)的答案简单、优雅,符合Python精神。

然而,存在问题:如果你尝试在"."以外的任何目录中运行它,它将失败,因为os.listdir()返回的是文件名而非完整路径。当列表当前工作目录时,这两者是相同的,因此在上面的源代码中错误未被检测到。

例如,如果你在/home/me处,并列出/tmp,你将得到(假设)['flashXVA67']。你将测试/home/me/flashXVA67而不是上述方法中的/tmp/flashXVA67

你可以使用os.path.join()来修复这个问题,像这样:

import os.path
path = './whatever'
count = len([f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))])

另外,如果您需要频繁进行计数并要求性能,可能需要在不生成其他列表的情况下完成。以下是一种不太优雅、不符合Python风格但高效的解决方案:

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


# The following line prints the number of files in the current directory:
path = "./whatever"
print fcount(path)

看一下bstpierre的答案。 - SilentGhost
确实!看起来比我的好,如果你正在阅读这篇内容,请回到第一个答案,Mark使用walk()添加了一行代码,解决了我指出的两个问题。 - salezica
+1 点赞发现了这个 bug - 我已经更新了我的回答,使用了你的修正版本。 - Mark Byers

1

试试这个:

import os
for dirpath, dirnames, filenames in os.walk('./your/folder/path'):
    print(f'There are {len(dirnames)} directories and {len(filenames)} images in {dirpath}.')

结果将会是这样的:
There are 10 directories and 0 images in ./asl_data/photos.
There are 0 directories and 32 images in ./asl_data/photos\0.
There are 0 directories and 34 images in ./asl_data/photos\1.
There are 0 directories and 32 images in ./asl_data/photos\2.
There are 0 directories and 31 images in ./asl_data/photos\3.
There are 0 directories and 34 images in ./asl_data/photos\4.
There are 0 directories and 31 images in ./asl_data/photos\5.
There are 0 directories and 40 images in ./asl_data/photos\6.
There are 0 directories and 33 images in ./asl_data/photos\7.
There are 0 directories and 30 images in ./asl_data/photos\8.
There are 0 directories and 39 images in ./asl_data/photos\9.

1
我认为最简单的方法是使用pathlib并检查iterdir()方法结果的长度。例如:
from pathlib import Path


search_path = Path('<relative or absolute path>')
n_files = len([*search_path.iterdir()])

如果你只想要特定类型的文件,你可以自定义列表推导式:

# only files
n_files = len([p for p in search_path.iterdir() if p.is_file()])

# only directories
n_files = len([p for p in search_path.iterdir() if p.is_dir()])

# only given extension
ext = '.png'
n_files = len([p for p in search_path.iterdir() if p.suffix==f'{ext}'])

0
print(len(os.listdir(r"你的路径")))

你的回答可以通过提供更多的支持性信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的回答是否正确。你可以在帮助中心找到关于如何撰写好回答的更多信息。 - undefined

0

递归解决方案:

sum(len(fs) for _,_,fs in os.walk(os.getcwd()))

对于当前目录的解决方案:

len(os.walk(os.getcwd()).next()[2])

0
total = len(filter(
            lambda f: os.path.isfile(os.path.join(path_to_dir, f)),
            os.listdir(path_to_dir)))

或者

total = sum([True for f in os.listdir(path_to_dir) if os.path.isfile(os.path.join([path_to_dir, f)])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接