Pythonでテキストファイル(.txt)の中身を読み書き・加工する方法【with/open/SQLへの変換】
目次
こんにちは。
今日はPythonでテキストファイル(.txt)を読み込んだり書き込んだりする方法をまとめます。
テキストファイルを読み書きするモチベーション
ファイル形式は.txt
でなくとも何でもいいのですが、テキストを読み書きしたいケースがいくつかあります。
テキストファイルに書いたリストを読み込んで楽に加工したい
モチベーションの1つ目としては、テキストに書いたリストを読み込んで加工したい。
具体的には、例えば以下のような文字列のリストにすべて同じ処理を施したいとき、リストの要素が100個とかあると手作業で行うと面倒ですよね。
アデリーペンギン
ジェンツーペンギン
ヒゲペンギン
...
↑これを ↓例えばこうしたい
「アデリーペンギン」
「ジェンツーペンギン」
「ヒゲペンギン」
...
もう少し業務に実用的な例だと、例えば上記のようなペンギンのリストをテキスト形式で受け取って、それをSQLデータベースの抽出条件に変換したいとき、クォーテーションで囲ったり同じ文言を前後につけたりする場合があります。
where SPECIES in ("アデリーペンギン","ジェンツーペンギン","ヒゲペンギン", ...
)
SQLで処理するには上のようなSQLが解釈できる文字列にする必要があります。前後に""
と,
がついてますね。これを手で書いても作ることができますが、数が多いと面倒なのでPythonでやってしまおうということ。(リストをテーブル化してJOINした方が適切だと思いますが、それができないケースもあるので...)
文字列の変換はExcelとかでもできそうですが、Pythonの方がアプリケーションに組み込んだり実行を自動化できたりするので便利です。
Pythonアプリケーションが使う変数のコンフィグファイルを作りたい
モチベーション2つ目は、設定値をファイルに保存しておくときです。
たとえばPythonアプリケーションの中で使われる何らかの設定値(変数の値やリスト)をアプリケーションコードの外に保存しておきたいというケース。Pythonの中をいちいち編集せずとも、テキストファイルを開いてその中身だけ書き換えることで設定変更作業が簡単になります。
Pythonでテキストファイルを読み込む
Pythonでテキストファイルをすべて読み込む
以下でテキストファイルを読み込み、中身をtxt
という変数に格納しています。
pathname = 'data'
filename = 'penguins.txt'
with open(f'{pathname}/{filename}','r') as f:
txt = f.read()
with open(path,'r') as f:
は定形として覚えてOKです。r
はreadの頭文字で、「path
のファイルを読み込みモードで開き、そのファイルをf
として扱う」という感じの書き方です。with
はopen
と使うことで、ファイルを閉じる命令を省略することができます。
read()
で読み込むことができ、その値を格納したtxt
の中身は以下のようになっています。
'アデリーペンギン\nジェンツーペンギン\nヒゲペンギン'
なんか間に文字化けみたいな\n
が入っていますが、これは改行コードというやつで、そこで行が変わっていることを示しています。
今回は読み込んだ内容をリストとして扱いたいので、上のような一つの文字列ではなく、1行ずつの文字列を要素に持ったリストを作る方法を使います。
Pythonでテキストファイルを1行ずつ読み込む
reaadlines
で1行ずつ読み込んでリストにできます。
with open(f'{pathname}/{filename}','r') as f:
l = f.readlines()
l
の中身は以下のように配列になっています。
['アデリーペンギン\n', 'ジェンツーペンギン\n', 'ヒゲペンギン']
ってお前(\n
)も入るんかい〜!ってことでこれを除外します。
要素の前後についた改行コードや余計なスペースなどをまとめて消すメソッドとして.strip()
が使えます。
lstrip = [s.strip() for s in l] # 各要素にstripを適用
# 結果
# ['アデリーペンギン', 'ジェンツーペンギン', 'ヒゲペンギン']
無事消えました。(strip
では文字列の途中にあるスペースは消えません。前後にある場合のみ消えます。)
読み込み時にstrip()
を使うとさらに簡潔に書けます。ここまでをまとめると以下のようになります。
pathname = 'data'
filename = 'penguins.txt'
with open(f'{pathname}/{filename}','r') as f:
l = [s.strip() for s in f.readlines()]
テキストファイルで読み込んだリストを加工する
冒頭に書いたようなリストの要素に同じ文字を付加したい場合。
色々やり方はあると思いますが、私の場合は一旦Pandasのデータフレームに変換してから一括で処理します。
import pandas as pd
# lをデータフレームに変換 列名設定
df = pd.DataFrame(l,columns=['species'])
# 前後に同じ文字列を追加した列を作成
df['sql'] = '"' + df['species'] + '",'
# 結果列をリスト形式に変換
outl = df['sql'].tolist()
同じ文字列付加だけであれば少し過剰ですが、DataFrameのメソッドが使えるようになるので、加工の自由度が高いです。
ただ、ダブルクォーテーションとカンマをつけたいくらいであれば、リスト上で処理した方が簡単です。
# lの各要素の前後にダブルクォーテーションを追加
l2 = [f'"{s}"' for s in l]
# l2の各要素をカンマで結合
outs = ','.join(l2)
# 結果
# "アデリーペンギン","ジェンツーペンギン","ヒゲペンギン"
join
メソッドは任意の文字列を区切り文字にしてリストを1つの文字列に結合できます。join
はリストではなく文字列のメソッドで、引数の方にリストをとります。逆にしないよう注意です。
リストをテキストファイルに書き込む
改行せずに書き込む方法
加工したリストを結合した文字列outs
を書き込みたい場合
out_pathname = 'output'
out_filename = 'penguins2.txt'
with open(f'{out_pathname}/{out_filename}','w') as f:
f.write(outs)
ここでファイルが存在しない場合はファイルが新規作成されますが、フォルダ(ディレクトリ)が存在しない場合はエラーになるので、予めフォルダを作っておく必要があります。
outpu
という存在しないフォルダのファイルを指定した場合↓ ファイルノットファウンドエラー。
FileNotFoundError: [Errno 2] No such file or directory: 'outpu/penguins2.txt'
また、writelines
でリスト要素を結合して書き込むこともできます。
with open(f'{out_pathname}/{out_filename}','w') as f:
f.writelines(l2)
でも文字列ではなくてリストを書き込むときは、要素ごとに改行して書き込みたいですよね。
改行して1行ずつ書き込む方法
というわけで加工したリストl2
を1行ずつ書き込みたい場合
with open(f'{out_pathname}/{out_filename}','w') as f:
f.write('\n'.join(l2))
またjoin
が出てきました。改行コードで要素を結合してから書き込めばいいんですね。
\n
、いいやつだったのか。
まとめ
というわけで、今回はPythonでテキストファイルに書かれたリストを読み込んで、加工したりファイルに出力したりする方法をまとめてみました。
Pythonアプリケーションのコンフィグファイルとしてテキストファイルを使いたい場合も同じようにファイルから読み込んで変数に格納すればよいですね。
ご参考になれば。