質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

1回答

3366閲覧

pythonでフォルダ名&ファイル名の一覧を理想の配列で出力したい

ot1982

総合スコア6

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

多次元配列

1次元配列内にさらに配列を格納している配列を、多次元配列と呼びます。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2020/11/04 11:56

python初めて2か月ほどの初心者です。
pythonでフォルダ名とファイル名を理想の配列で出力したいです。2次元リストをデータフレームにして出力することはできました。しかし理想の配列で出力するにはどのようすれば良いでしょうか。

まず、下図のようなフォルダ階層があるとします。
イメージ説明
testフォルダの中にプログラム実行ファイルを置いて実行すると下図のイメージような配列で出力したいです。
イメージ説明

現状作成したプログラムで2次元リストをデータフレームにして出力することはできました。

import pandas as pd import os path = os.getcwd() print("working directory is" , path) # ディレクトリ階層+中身 が各列に入る2次元リストを作る # [['AAA'], # ['AAA', 'test1.xlsx'], # ['AAA', 'BBB'], # ['AAA', 'BBB', 'test2.xlsx'], # ...] pathlist = [] for curDir, dirs, files in os.walk(path): leaf = curDir.split('/') pathlist.append(leaf) for a_dir in dirs: pathlist.append(leaf + [a_dir]) for a_file in files: pathlist.append(leaf + [a_file]) print(pathlist) # 作った2次元リストをデータフレームにする path_df = pd.DataFrame(pathlist) print(path_df)

イメージ説明

ここから理想の配列で出力するにはどうすれば良いでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

LouiS0616

2020/11/04 12:23

ディレクトリ名, 深さ, ファイル名(orディレクトリ名) の3属性にした方が扱いやすい気がするのですが、どうでしょう。
guest

回答1

0

提示されている実行結果から、環境は Windows と推定しています。

Python

1import pandas as pd 2import os 3#path = os.getcwd() 4org = path = os.getcwd() 5print("working directory is" , path) 6# ディレクトリ階層+中身 が各列に入る2次元リストを作る 7# [['AAA'], 8# ['AAA', 'test1.xlsx'], 9# ['AAA', 'BBB'], 10# ['AAA', 'BBB', 'test2.xlsx'], 11# ...] 12pathlist = [] 13 14for curDir, dirs, files in os.walk(path): 15 #leaf = curDir.split('/') 16 #pathlist.append(leaf) 17 #dum = 0 if curDir == org else len(curDir[len(org)+1:].split('\')) 18 dum = curDir.count('\') - org.count('\') # コードを改善 19 for a_dir in dirs: 20 #pathlist.append(leaf + [a_dir]) 21 pathlist.append([curDir] + [''] * dum + [a_dir]) 22 for a_file in files: 23 #pathlist.append(leaf + [a_file]) 24 pathlist.append([curDir] + [''] * dum + [a_file]) 25print(pathlist) 26mx = max(len(s) for s in pathlist) 27pathlist = [s + [''] * (mx - len(s)) for s in pathlist] 28# 作った2次元リストをデータフレームにする 29path_df = pd.DataFrame(pathlist) 30print(path_df)

行出力を深さ優先にしたコード

Python

1import pandas as pd 2import os 3 4def make_pathlist(path): 5 pathlist = [] 6 for curDir, dirs, files in os.walk(path): 7 dum = curDir.count('\') - org.count('\') 8 for a_dir in dirs: 9 pathlist.append([curDir] + [''] * dum + [a_dir]) 10 for a_file in files: 11 pathlist.append([curDir] + [''] * dum + [a_file]) 12 mx = max(len(s) for s in pathlist) 13 return [s + [''] * (mx - len(s)) for s in pathlist] 14 15def conv_to_depthfirst(pathlist): 16 for i in range(len(pathlist)): 17 for j in range(1, len(pathlist[i])): 18 dir = os.path.join(pathlist[i][0], pathlist[i][j]) 19 if pathlist[i][j] and os.path.isdir(dir): 20 zs = ze = 0 21 for k in range(i+1, len(pathlist)): 22 if pathlist[k][0].find(dir) >= 0: 23 if zs == 0: 24 zs = ze = k 25 else: 26 ze = k 27 else: 28 if zs > 0: 29 break 30 if zs > i + 1: 31 # zs ~ ze を i と i + 1 の間に挿入する 32 return conv_to_depthfirst(pathlist[0:i+1] + pathlist[zs:ze+1] + pathlist[i+1:zs] + pathlist[ze+1:]) 33 return pathlist 34 35org = path = os.getcwd() 36print("working directory is" , path) 37# ディレクトリ階層+中身 が各列に入る2次元リストを作る 38pathlist = make_pathlist(path) 39pathlist = conv_to_depthfirst(pathlist) # 深さ優先順に変換 40 41# 作った2次元リストをデータフレームにする 42path_df = pd.DataFrame(pathlist) 43print(path_df)

投稿2020/11/04 13:55

編集2020/11/05 13:27
lehshell

総合スコア1156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ot1982

2020/11/04 23:05

lehshellさん ご回答ありがとうございます。環境はwindowsです。コードを実行して確認すると、理想の配列に近くなったのを確認できました。出力結果を見て疑問があるのですが、1列目の1行目(AAA)以降に出力されるフォルダやファイル名(DDD、スクリプト名、か.xls)を理想の行に出力するにはどうすればよいですか。配列の検討だけでは実現するのは難しいものなのでしょうか。
lehshell

2020/11/05 13:33

行出力を深さ優先にしたいということですね。該当コードを追記しました。 ベタなコードなので冴えませんが。。。 再帰の深さを心配する場合は #return conv_to_depthfirst(pathlist[0:i+1] + pathlist[zs:ze+1] + pathlist[i+1:zs] + pathlist[ze+1:]) return pathlist[0:i+1] + pathlist[zs:ze+1] + pathlist[i+1:zs] + pathlist[ze+1:] として #pathlist = conv_to_depthfirst(pathlist) # 深さ優先順に変換 while (tmp := conv_to_depthfirst(pathlist)) is not pathlist: pathlist = tmp と繰り返し conv_to_depthfirst() を呼び出す形式にしてください。
ot1982

2020/11/06 13:09

返事遅くなりすみません。理想のレイアウトに出力できたのが確認できました。追記のコードも含め、ありがとうございます。コードの中身の理解に努めたいと思います。不明点があればご質問させていただくかもしれませんが、その時はよよろしくお願いいたします。
ot1982

2020/11/12 22:42

lehshellさん 先日はご回答ありがとうございました。今週頂いたコードを読み解く作業をしていたのですが、初心者の私には複雑すぎてよくわからない状況です。私なりに調べてコードの各行にコメントで何をしているかを書き出してみましたが分からない行は、疑問文でコメントを書いています。 import pandas as pd import os def make_pathlist(path): #pathlistを作成する pathlist = [] #[]をpathlistに代入する for curDir, dirs, files in os.walk(path): #指定したディレクトリからトップダウンの流れでディレクトリを走査 dum = curDir.count('\') - org.count('\') #ここでは何を変数に代入しているのか?? for a_dir in dirs: #各ディレクトリの一覧を取得 pathlist.append([curDir] + [''] * dum + [a_dir]) #ここでは何をしているのか?? for a_file in files: #各ファイルの一覧を取得 pathlist.append([curDir] + [''] * dum + [a_file]) #ここでは何をしているのか?? mx = max(len(s) for s in pathlist) #ここでは何を変数に代入しているのか?? return [s + [''] * (mx - len(s)) for s in pathlist] #何の戻り値を返しているのか? def conv_to_depthfirst(pathlist): #深さ優先順に変換 for i in range(len(pathlist)): #0からpathlistの数を超えないを範囲で繰り返し処理をする for j in range(1, len(pathlist[i])): #ここから下の行は何をしているのか?? dir = os.path.join(pathlist[i][0], pathlist[i][j]) if pathlist[i][j] and os.path.isdir(dir): zs = ze = 0 for k in range(i+1, len(pathlist)): if pathlist[k][0].find(dir) >= 0: if zs == 0: zs = ze = k else: ze = k else: if zs > 0: break if zs > i + 1: # zs ~ ze を i と i + 1 の間に挿入する return conv_to_depthfirst(pathlist[0:i+1] + pathlist[zs:ze+1] + pathlist[i+1:zs] + pathlist[ze+1:]) return pathlist 主に、for文での処理が作業段階ごとにprintなどで出力できれば、ここでは何の作業をしているのだなと把握しやすいのですが、そのようなことってできるのでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問