37

ファイルやフォルダを割り当てたり、+=[item]の部分を実行したりするのは少しハックだと思います。助言がありますか?Python3.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
4

12 に答える 12

39

os.walkパスとそれに含まれるディレクトリおよびファイルを返す関数を見てください。それはあなたの解決策をかなり短くするはずです。

于 2011-07-10T05:34:50.833 に答える
28

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}")


于 2020-09-09T02:23:29.817 に答える
21

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

于 2020-11-19T16:32:57.197 に答える
4

確かに使用

items += [item]

多くの理由で悪いです...

  1. appendメソッドはまさにそのために作られました(リストの最後に1つの要素を追加します)

  2. 1つの要素の一時的なリストを作成して、それを破棄します。Pythonを使用する場合(そうでない場合は間違った言語を使用している場合)、生の速度を最初に気にする必要はありませんが、理由もなく速度を浪費することは正しいことではないようです。

  3. Python言語の少しの非対称性を使用しています...リストオブジェクトの書き込みa += bは書き込みと同じではありませんa = a + b。前者はオブジェクトを所定の位置に変更し、2番目は代わりに新しいリストを割り当て、オブジェクトがオブジェクトの場合は異なるセマンティクスを持つ可能性があるためです。a他の方法を使用して到達することもできます。あなたの特定のコードではこれは当てはまらないようですが、後で誰か(または数年後にはあなた自身)がコードを変更しなければならないときに問題になる可能性があります。Pythonにはextend、別のリストの要素を最後に追加することによってリストオブジェクトをその場で変更する場合を処理するために特別に作成された、それほど微妙でない構文のメソッドもあります。

また、他の人が指摘しているように、あなたのコードはすでに行っていることを行おうとしているようos.walkです...

于 2011-07-10T06:12:17.890 に答える
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
于 2011-07-10T05:42:59.977 に答える
3

サブフォルダー内のすべてのファイルを含むすべてのファイルを再帰的に反復処理する場合は、これが最善の方法だと思います。

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)
于 2016-06-13T09:14:17.873 に答える
3

Python 3.4以降、新しいモジュールがありますpathlib。したがって、すべてのdirとファイルを取得するには、次のようにします。

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()]
于 2017-12-07T10:10:14.173 に答える
1

組み込みのos.walkとos.path.walkの代わりに、元々リンクしていたがインラインソースに置き換えた他の場所で提案されたこのコードから派生したものを使用します。

import os
import stat

class DirectoryStatWalker:
    # a forward iterator that traverses a directory tree, and
    # returns the filename and additional file information

    def __init__(self, directory):
        self.stack = [directory]
        self.files = []
        self.index = 0

    def __getitem__(self, index):
        while 1:
            try:
                file = self.files[self.index]
                self.index = self.index + 1
            except IndexError:
                # pop next directory from stack
                self.directory = self.stack.pop()
                self.files = os.listdir(self.directory)
                self.index = 0
            else:
                # got a filename
                fullname = os.path.join(self.directory, file)
                st = os.stat(fullname)
                mode = st[stat.ST_MODE]
                if stat.S_ISDIR(mode) and not stat.S_ISLNK(mode):
                    self.stack.append(fullname)
                return fullname, st

if __name__ == '__main__':
    for file, st in DirectoryStatWalker("/usr/include"):
        print file, st[stat.ST_SIZE]

ディレクトリを再帰的にウォークし、非常に効率的で読みやすいです。

于 2011-07-20T04:53:07.653 に答える
0

appendメソッドを使用してみてください。

于 2011-07-10T05:37:17.510 に答える
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)
于 2015-02-24T07:52:54.023 に答える
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)
        )
    )
于 2015-07-18T06:55:13.063 に答える
0

Python >= 3.4ジェネレータメソッドが存在するためPath.rglob。したがって、すべてのパスを処理するsome/starting/pathには、次のようなことを行います。

from pathlib import Path

path = Path('some/starting/path') 
for subpath in path.rglob('*'):
    # do something with subpath

リスト内のすべてのサブパスを取得するには、を実行しますlist(path.rglob('*'))sql拡張子が 付いたファイルだけを取得するには、を実行しますlist(path.rglob('*.sql'))

于 2022-02-22T15:35:28.887 に答える