走一个目录树的Python方法是什么?

时间:2011-07-10 05:31:55

标签: python directory-walk

我觉得分配文件和文件夹以及执行+ = [item]部分有点hackish。有什么建议?我正在使用Python 3.2

from os import *
from os.path import *

def dir_contents(path):
    contents = listdir(path)
    files = []
    folders = []
    for i, item in enumerate(contents):
        if isfile(contents[i]):
            files += [item]
        elif isdir(contents[i]):
            folders += [item]
    return files, folders

11 个答案:

答案 0 :(得分:33)

查看os.walk函数,该函数返回路径及其包含的目录和文件。这应该会大大缩短你的解决方案。

答案 1 :(得分:4)

确实使用

items += [item]

有很多原因......

  1. append方法已经完全(将一个元素追加到列表末尾)

  2. 您正在创建一个元素的临时列表,只是为了抛弃它。虽然原始速度不应该是你使用Python时的第一个问题(否则你使用了错误的语言)仍然无缘无故地浪费速度似乎是不对的。

  3. 您使用的是Python语言的一点不对称...对于编写a += b的列表对象与编写a = a + b不同,因为前者修改了对象,而第二,而是分配一个新列表,如果对象a也可以使用其他方式访问,则它可以具有不同的语义。在您的特定代码中,这似乎并非如此,但是当其他人(或者您自己在几年内,即相同的)将不得不修改代码时,它可能会成为一个问题。 Python甚至有一个方法extend,其语法不太精细,专门用于处理你希望通过在末尾添加另一个列表的元素来修改列表对象的情况。

    < / LI>

    另外正如其他人所说,您的代码似乎正在尝试执行os.walk已经执行的操作...

答案 2 :(得分:3)

def dir_contents(path):
    files,folders = [],[]
    for p in listdir(path):
        if isfile(p): files.append(p)
        else: folders.append(p)
    return files, folders

答案 3 :(得分:3)

os.walkos.scandir是不错的选择,但是,我越来越多地使用 pathlib ,有了pathlib,您可以使用.glob()方法:

root_directory = Path(".")
for path_object in root_directory.glob('**/*'):
    if path_object.is_file():
        print(f"hi, I'm a file: {path_object}")
    elif path_object.is_dir():
        print(f"hi, I'm a dir: {path_object}")


答案 4 :(得分:2)

而不是内置的os.walk和os.path.walk,我使用的是从我在其他地方建议的这段代码中派生的东西:

http://code.google.com/p/mylibs/source/browse/lib/Python/MyPyLib/DirectoryStatWalker.py

我不会在这里重复它,但是它会递归地遍历目录并且非常高效且易于阅读。

答案 5 :(得分:2)

如果你想递归遍历所有文件,包括子文件夹中的所有文件,我相信这是最好的方法。

import os

def get_files(input):
    for fd, subfds, fns in os.walk(input):
       for fn in fns:
            yield os.path.join(fd, fn)

## now this will print all full paths

for fn in get_files(fd):
    print(fn)

答案 6 :(得分:2)

从Python 3.4开始,有新的模块pathlib。因此,要获得所有目录和文件:

from pathlib import Path

dirs = [str(item) for item in Path(path).iterdir() if item.is_dir()]
files = [str(item) for item in Path(path).iterdir() if item.is_file()]

答案 7 :(得分:1)

对于使用pathlibpython >= 3.4)寻找解决方案的任何人

from pathlib import Path

def walk(path): 
    for p in Path(path).iterdir(): 
        if p.is_dir(): 
            yield from walk(p)
            continue
        yield p.resolve()

# recursively traverse all files from current directory
for p in walk(Path('.')): 
    print(p)

# the function returns a generator so if you need a list you need to build one
all_files = list(walk(Path('.'))) 

但是,如上所述,这并不保留os.walk给出的自上而下的顺序

答案 8 :(得分:0)

尝试使用append方法。

答案 9 :(得分:0)

在搜索相同的信息时,我发现了这个问题。

我在这里发布了我在http://www.pythoncentral.io/how-to-traverse-a-directory-tree-in-python-guide-to-os-walk/找到的最小,最清晰的代码(而不是仅仅发布URL,以防链接腐烂)。

该页面包含一些有用的信息,并指向其他一些相关页面。

# Import the os module, for the os.walk function
import os

# Set the directory you want to start from
rootDir = '.'
for dirName, subdirList, fileList in os.walk(rootDir):
    print('Found directory: %s' % dirName)
    for fname in fileList:
        print('\t%s' % fname)

答案 10 :(得分:0)

我还没有对此进行过广泛的测试,但我相信  这将扩展os.walk生成器,将dirnames连接到所有文件路径,并展平结果列表;在搜索路径中提供具体文件的直接列表。

import itertools
import os

def find(input_path):
    return itertools.chain(
        *list(
            list(os.path.join(dirname, fname) for fname in files)
            for dirname, _, files in os.walk(input_path)
        )
    )