Как Python способ обходить дерево каталогов? - PullRequest
22 голосов
/ 10 июля 2011

Я чувствую, что назначение файлов, папок и выполнение части + = [item] немного странно.Какие-либо предложения?Я использую 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

Ответы [ 9 ]

33 голосов
/ 10 июля 2011

Посмотрите на функцию os.walk, которая возвращает путь вместе с каталогами и файлами, которые в нем содержатся.Это должно значительно сократить ваше решение.

4 голосов
/ 10 июля 2011

Действительно, используя

items += [item]

плохо по многим причинам ...

  1. Для этого был выбран append метод точно (добавление одного элемента в конец списка)

  2. Вы создаете временный список из одного элемента, чтобы просто выбросить его. Хотя грубая скорость не должна вас беспокоить при использовании Python (в противном случае вы используете не тот язык), тем не менее бесполезная потеря скорости кажется неправильной.

  3. Вы используете небольшую асимметрию языка Python ... для записи объектов списка a += b - это не то же самое, что запись a = a + b, поскольку первая изменяет объект на месте, а вторая вместо этого выделяет новый список, и он может иметь другую семантику, если объект a также доступен другими способами. В вашем конкретном коде это не так, но это может стать проблемой позже, когда кто-то другой (или вы сами через несколько лет, то же самое) должны будут изменить код. В Python даже есть метод extend с менее тонким синтаксисом, который специально создан для обработки случая, в котором вы хотите изменить вместо объекта списка, добавив в конце элементы другого списка.

Также, как уже отмечали другие, кажется, что ваш код пытается сделать то, что os.walk уже делает ...

3 голосов
/ 10 июля 2011
def dir_contents(path):
    files,folders = [],[]
    for p in listdir(path):
        if isfile(p): files.append(p)
        else: folders.append(p)
    return files, folders
2 голосов
/ 13 июня 2016

Если вы хотите рекурсивно перебирать все файлы, включая все файлы в подпапках, я считаю, что это лучший способ.

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)
2 голосов
/ 20 июля 2011

Вместо встроенных os.walk и os.path.walk я использую что-то, полученное из этого фрагмента кода, который я нашел в другом месте:

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

Я не буду здесь его повторять, но он рекурсивно просматривает каталоги, довольно эффективен и легко читается.

1 голос
/ 07 декабря 2017

Начиная с 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()]
0 голосов
/ 18 июля 2015

Я еще не проверял это подробно, но я верю, что это расширит генератор os.walk, объединит имена каталогов со всеми путями файлов и сгладит результирующий список;Чтобы получить прямой список конкретных файлов в вашем пути поиска.

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)
        )
    )
0 голосов
/ 24 февраля 2015

При поиске той же информации я нашел этот вопрос.

Я публикую здесь самый маленький и понятный код, который я нашел в 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)
0 голосов
/ 10 июля 2011

Попробуйте использовать метод append.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...