Ответ 1
Посмотрите на функцию os.walk
, которая возвращает путь вместе с каталогами и файлами, которые он содержит. Это должно значительно сократить ваше решение.
Я чувствую, что назначение файлов и папок и выполнение части + = [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
Посмотрите на функцию os.walk
, которая возвращает путь вместе с каталогами и файлами, которые он содержит. Это должно значительно сократить ваше решение.
Действительно, используя
items += [item]
плохо по многим причинам...
Для этого метода append
было сделано точно (добавление одного элемента в конец списка)
Вы создаете временный список одного элемента, чтобы просто выбросить его. В то время как сырая скорость не должна быть вашей первой проблемой при использовании Python (иначе вы используете неправильный язык), все еще теряя скорость без причины, не кажется правильным.
Вы используете небольшую асимметрию языка Python... для записи объектов списка a += b
это не то же самое, что писать a = a + b
, потому что первая изменяет объект на месте, а вторая вместо этого выделяет новый список, и это может иметь другую семантику, если объект a
также доступен другим образом. В вашем конкретном коде это не похоже на случай, но это может стать проблемой позже, когда кому-то другому (или самому себе через несколько лет, то же самое) придется модифицировать код. У Python даже есть метод extend
с менее тонким синтаксисом, который специально предназначен для обработки случая, когда вы хотите изменить на месте объект списка, добавив в конце элементы другого списка.
Также, как отмечали другие, кажется, что ваш код пытается сделать то, что уже делает os.walk
...
def dir_contents(path):
files,folders = [],[]
for p in listdir(path):
if isfile(p): files.append(p)
else: folders.append(p)
return files, folders
Вместо встроенного os.walk и os.path.walk я использую что-то, полученное из этого фрагмента кода, который я нашел в другом месте:
http://code.google.com/p/mylibs/source/browse/lib/Python/MyPyLib/DirectoryStatWalker.py
Я не буду отплачивать его здесь, но он рекурсивно просматривает каталоги и достаточно эффективен и легко читается.
Если вы хотите рекурсивно перебирать все файлы, включая все файлы в подпапках, я считаю, что это лучший способ.
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)
С 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()]
Попробуйте использовать метод append
.
Во время поиска по той же информации я нашел этот вопрос.
Я размещаю здесь самый маленький, самый ясный код, который я нашел в 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)
Я еще не тестировал этот экстенсив, но я верю
это расширит генератор 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)
)
)