
本来、不要だと思います。なぜなら、フォルダの再帰処理をまとめたライブラリはあります。しかし、私は今再帰処理に燃えています。覚えたてだからです。
今回は、再帰処理の根本から簡単な演習問題までを備忘録として残したいと思います。
再帰処理の基本
再帰処理ってどんなことなのか?をまとめてみましょう。そこで、再帰処理の基本を押さえてから、実際にコードを見ていただいた方がわかりやすいと思います。
自身を呼び出す形にする
終了条件を設定する
変化を加えながら終了条件へ進む
一番忘れやすい部分は、3つ目の変化を加えながら終了条件へ進む。という部分です。終了条件はなんとなくイメージはできているんですが、変化を加えることがすごい難しい印象があります。
フォルダを探索する再帰処理
フォルダを探索するときに、どういう仕組みにするかを考えるのが大変です。なぜなら、フォルダ階層は深さがまちまちでまた設計の時に深さがわかってたり、完全な定型的なフォルダ階層になっているのであれば、そもそも探索する必要性がありません。
なので、基本的には深さの概念とどこにどのくらいのファイルが入ってるのか?を決めることができない。だから、1つずつ答えを出してまとめるのが大事です。
1 2 3 4 5 6 7 8 9 10 11 |
SaikiFolder.py Folder0 ∟Folder1 ∟Test2.py ∟今回起動.py ∟Folder2 ∟Folder2_1 ∟Test4.py ∟Folder2_2 ∟Test5.py ∟Test3.py |
さて、今回はこういった階層構造のフォルダの探索を行う。上記のフォルダは、インポートの階層構造の説明で使ったフォルダ階層です。
Folder0のフォルダ構成を、SaikiFolder.pyにて調査をします。
SaikiFolder.pyのコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
import glob import os # 再起で深堀をしていくことで、フォルダの中身をすべて洗い出す # これですべての情報を取得することができる。 # FolderListは別で作らないと動かない。ここではリストを持っていないし、Returnもしていない。 def FolderSaiki(FolderAddress,FolderList,Fukasa=1): for i in os.listdir(FolderAddress): TmpStr = FolderAddress + '/' + i if os.path.isdir(TmpStr): FolderSaiki(TmpStr,FolderList,Fukasa+1) # 「アドレス」と「深さ」と「種別」 aaa = '\"'+TmpStr+'\",\"'+str(Fukasa)+'\",\"'+'Folder'+'\"' else: # 「アドレス」と「深さ」と「種別」 aaa = '\"'+TmpStr+'\",\"'+str(Fukasa)+'\",\"'+'File'+'\"' FolderList.append(aaa) def FolderStringList(MainAddress): # 追加をする場所を作る FolderList = [] FolderSaiki(MainAddress,FolderList) FolderList.sort() FileList = [] TypeList = [] AddressList = [] for i in FolderList: str1 = i.split('\",\"') # TmpStr = str1[0].replace('\"','') # 絶対パスに変換している場所 コメントアウトすると、相対パス('./')になる。 TmpStr = os.path.abspath(str1[0].replace('\"','')) # 格納場所 AddressList.append(TmpStr.split('\\')) FileList.append(str1[1].replace('\"','')) TypeList.append(str1[2].replace('\"','')) print(len(AddressList),AddressList) print(len(FileList),FileList) print(len(TypeList),TypeList) if __name__ == '__main__': for i in os.listdir('./'): print(i) a = input('上記のフォルダから選んで下さい。\n') a = './' + a FolderStringList(a) print('こっちの方法もある\n','glob.glob()で実行した結果\n',glob.glob(os.path.join(a, '**'), recursive=True)) |
上記環境を作って、一度これを実行してみてください。すると、フォルダの中身をくるくる回っていろいろと出してくれます。
一応、最後に入れているが、glob.glob()だけで再帰処理を再現することができる。つまり、今回何がやりたかったかというと、仕組みを自分で作ってみたかっただけ。
本当に簡単に終わらせるならglob.glob()でやってみるのが一番簡単で正確かも?
さいごに
ポイントは3つある。
自身を呼び出す形にする
終了条件を設定する
変化を加えながら終了条件へ進む
再帰処理は、コツさえつかめば何とかなるような感じに見えます。最初は難しいですし、僕もまだ完全にできているわけじゃないので偉そうに語れるものじゃないですけどね。
どんどん新しい技術を覚えて、アウトプットをしていきたいと思います。