クッキーもぐもぐ

PC関係とか映画とかゲームとかの

pythonでファイル読み込み→リストとして処理する方法

目的

  • pythonで簡単なデータを読み込む
  • 読み込んだデータを表示だけでなく、処理もしたい
  • 読みんだデータをリストに格納した

こんなデータを読み込んで、処理したい sample.txt

 5
 12 56 84
 45 65 66 65

読み込んだデータをそのまま表示するやり方は他の記事でも沢山あった。けどリストとかに入れて処理していきたい。atcoderだとinput()だけど、たまに他のテストだと用意されたデータを読み込んで処理するケースがあった。そのとき躓かないように、メモ。

方法

まとめて読み込んでリストへ格納

#テキスト読み込み
f = open(r"ファイルのパスとかデータ","r",encoding="utf-8")

#それぞれの行をまとめて取得する
lines = f.readlines()#各行がリストへ格納
f.close()

ぶっちゃけこれだけでOK。linesにデータがリストとして格納されている。うえのsample.txtだとlinesには

[' 5\n', ' 12 56 84\n', ' 45 65 66 65']

が入っている。

まとめて読み込んで格納+改行削除

改行を消したい場合は

#テキスト読み込み
f = open(r"ファイルのパスとかデータ","r",encoding="utf-8")
#それぞれの行をまとめて取得する
lines = f.readlines()#各行がリストへ格納

#改行を除く場合
for i,v in enumerate(lines):
    lines[i] = v.replace("\n", "")

#それぞれの行をまとめて取得する
lines = f.readlines()#各行がリストへ格納
f.close()
#lines
[' 5', ' 12 56 84', ' 45 65 66 65']

リストとして落とし込めたので、あとは煮るなり焼くなり好きにできる。

すっきり版

改行削除くらいなら内容表記ですっきりできる

#テキスト読み込み
f = open(r"ファイルのパスとかデータ","r",encoding="utf-8")
#それぞれの行をまとめて取得する
lines = f.readlines()#各行がリストへ格納
lines = [v.replace("\n", "") for v in lines]
f.close()

さらに色々処理もできる

sample.txtやatcoderの問題のように各行がさらにスペースで区切られたデータの場合、

for i,v in enumerate(lines):
    lines[i] = v.replace("\n", "")
    lines[i]= list(map(int,(lines[i].split())))

のようにsplitでわけてintに変換→リスト化で

#lines
[[5], [12, 56, 84], [45, 65, 66, 65]]

にように綺麗にできる。(いらないかもだけど)

一行ずつの場合 (確認専用?)

f = open(r"ファイルのパスとかデータ",encoding="utf-8")
for line in f:
    line = line.replace("\n", "")#改行を消す場合
    #何か処理
f.close()

一行ずつ処理する場合は上のようになる。ただその都度の処理になるので、データを後から処理したい場合、一旦なにかに格納し直す必要がある。.append(line)みたいに。表示だけの確認用ならいいけど、処理を考えたらやっぱりまとめて読み込んで格納したほうがいいかも

特定の行だけ読み込む (n行目指定)

一方で特定の行だけ処理をしたい場合は、一行ずつ読み込む方法も有用。膨大なデータでn行目だけ取り出したい!というときはenumerateでindexをとりだし、if文で判定すればよい。

f = open(r"ファイルのパスとかデータ",encoding="utf-8")
n = 1
line = [v.replace("\n", "") for i,v in enumerate(f) if i==n]
f.close()
#line #1行目をとりだす(0行スタート)
[' 12 56 84']

特定の行だけ読み込む (文字列判定)

他にも特定の文字列が含んでいる行だけ取り出す場合とかも便利。また内包表記を使えば、取り出した行が複数個あっても追加してくれるので便利。

f = open(r"ファイルのパスとかデータ",encoding="utf-8")
target = '6'
lines = [i.replace("\n", "") for i in f  if target in i]
f.close()
#lines 6が含まれる列だけ取り出す
[' 12 56 84', ' 45 65 66 65']

jsonの場合

入力データ

#sample.json
{
    "name": "亀仙人",
    "age":354
}

を読み込む場合

import json
f = open(r"ファイルのパスとかデータ",encoding="utf-8")
data = json.load(f)
f.close()
#sample.json
{'name': '亀仙人', 'age': 354}

まとめ

  • とりあえず全部読んで処理したい→.readlines()で各行をリストへ格納
  • 特定の行だけ絞って処理したい→i in fで、iに対して条件文
  • 内包表記を使うとリストの定義もappendも必要なくて便利