色々な方法があるが、基本的な手順は同じである。
- ファイルをオープンする。
- データを読み込む。
1番目は変わらない。2番目の読み込み方に色々な方法がある。
- ファイルの種類により使用する関数を変える
- ファイルの読み込み方を変える(ファイル全体、1行ずつ)
ファイルの読み込み方の概要をつかんでおいて、必要なものを深く調べるという学び方ができるようメモをまとめた。
環境
- Python 3.7.4
フォルダ構成
data_read_test
├──data
│ ├──test.json
│ └──test.csv
├──data_read_test_1.py
├──data_read_test_2.py
├──data_read_test_3.py
├──json_read_test.py
└──csv_read_test.py
#ファイルオープンの方法
##組み込み関数open()
組み込み関数open(path, mode)
を使う。
path
には読み込み対象ファイルのパスを設定する
mode
は、ファイルをオープンする時に目的に応じて設定しなければならない。読み込みの場合は"r"とする。"r"はデフォルト値なので省略可能だが、他に"w"書き込み、"a"追記などがある。
'''
ファイルオープンのサンプル
'''
path = 'data/test.json' #読み込み対象ファイル
mode = "r" #ファイルモード r:読み込み
f = open(path, mode) #ファイルをオープンする
pass #ここにデータを読み込む処理を記述する
f.close() #オープンしたファイルは、必ずクローズすること
##withブロックの使用
with
ブロックを使うとブロック終了時にファイルが自動的にクローズされる。クローズ忘れのミスが起こりにくなるので便利。
'''
ファイルオープンのサンプル(withブロック)
'''
path = 'data/test.json' #読み込み対象ファイル
mode = "r" #ファイルモード r:読み込み
with open(path, mode) as f:
pass #ここにデータを読み込む処理を記述する
# f.close()は不要
# withブロックを使うと、ファイルが自動的にクローズされる
#テキストデータを読み込む
##ファイル全体を文字列として読み込む
open
したファイルオブジェクトに対して、read
メソッドを使う。
サンプルコードでは、読み込み対象ファイルにJSONファイルを指定しているが、JSONファイルもテキストファイルなので、read
メソッドにより、ファイル全体が文字列として読み込まれる。データタイプ(Type of "data")はstr
となる。
ただし、read
メソッドは文字列として読むだけなので、JSON形式としては識別されない。
def data_read_test1(path, mode):
"""
ファイル全体を文字列(str型)で読み込む
"""
with open(path, "r") as f:
data = f.read() #ファイル全体を読み込む
return(data)
if __name__ == "__main__":
#読み込み対象ファイル
path = 'data/test.json'
#ファイルモード
mode = "r" #読み込み用
data = data_read_test1(path, mode)
print("Type of ""data"":{}".format(type(data)))
print("---- All data ----")
print(data)
読み込み対象ファイルの内容。
{
"book1":{
"title":"Evil Boy",
"author":"B.T."
},
"book2":{
"title":"Grappler",
"author":"H.B."
}
}
##行単位のリストとして読み込む
read
メソッドは、ファイル全体を一塊の文字列データとして読み込む。1行ずつ処理したいときは、readlines
メソッドを使う。readlines
メソッドで読み込むと、データタイプ(Type of "data")がlist
となる。
def data_read_test2(path, mode):
"""
1行ずつ処理できるよう行単位のリスト(list型)として読み込む
"""
with open(path, "r") as f:
data = f.readlines() #行単位のリストとして読み込む
return(data)
if __name__ == "__main__":
#読み込み対象ファイル
path = 'data/test.json'
#ファイルモード
mode = "r" #読み込み用
data = file_read_test2(path, mode)
print("Type of ""data"":{}".format(type(data))) #strではなくlist
print("---- All data ----")
print(data)
print("---- Each line ----")
for line in data:
print(line) #1行ずつ処理できる
##ファイルから1行ずつ読み込む
read
メソッドやreadlines
メソッドは、ファイルをすべてメモリに読み込んでしまう。読み込み対象ファイルのサイズが巨大で、それが問題となる場合は、readline
メソッド("s"なし)で1行ずつ読み込む。
readline
メソッドは、1行だけ読み込むがある。もう一度読み込むと、次の行が読み込まれる。
このような1行ずつ読み込む概念を詳しく知りたい場合は、「イテレータ」や「next() メソッド」を調べてみるとよい。
def data_read_test3(path, mode):
"""
ファイルから1行ずつ読み込む
"""
with open(path, mode) as f:
row = f.readline() #1行目を読み込む
while row:
print("---- Row data ----")
print("Type of ""data"":{}".format(type(row))) #str型
print(row)
row = f.readline() #次の行を読み込む
if __name__ == "__main__":
#読み込み対象ファイル
path = 'data/test.json'
#ファイルモード
mode = "r" #読み込み用
data_read_test3(path, mode)
#JSON形式のデータを読み込む
open
したファイルオブジェクトに対して、jsonライブラリのload
メソッドを使う。load
メソッドを使うと、データをJSON形式として識別し、dict型に変換して読み込んでくれる。load
メソッドで読み込むと、データタイプ(Type of "data")がdict
となる。
from json import load
def json_read_test(path, mode):
"""
JSONファイル全体をdict型で読み込む
"""
with open(path, mode) as f:
data = load(f)
return(data)
if __name__ == "__main__":
#読み込み対象ファイル
path = 'data/test.json'
#ファイルモード
mode = "r" #読み込み用
data = json_read_test(path, mode)
print("Type of ""data"":{}".format(type(data))) #strでもlistでもなくdict
print("---- All data ----")
print(data)
print("---- Key data ----")
for key in data:
print(key) #json形式をdict型に変換しているので、例えば、keyのみを取り出せる
#csv形式のデータを読み込む
##ファイルから1行ずつ読み込む
open
したファイルオブジェクトに対して、csvライブラリのreader
メソッドを使う。reader
メソッドを使うと、データをcsv形式として識別し、読み込んでくれる。
これまでと異なるのは、ファイルをクローズしてしまうと、dataの中から1行ずつ取り出せなくなるので、withブロックの中で処理していることである。
追記2020-01-01
このケースだけ、書き方が異なるのが悔しくて、同じような書き方になるよう検討しVer2を記述した。なお、withブロックの中にデータ処理を延々と書いていくというのは、読みやすいコードにならないと思う。
from csv import reader
def csv_read_test(path, mode):
"""
csvファイル全体を読み込み行や要素を取り出す
"""
with open(path, mode) as f:
data = reader(f)
for row in data:
print("---- Row data ----")
print("Type of ""data"":{}".format(type(row))) #list型
print(row) #1行取り出せる
print("---- Element data ----")
print("Type of ""data"":{}".format(type(row[0]))) #str型
print(row[0]) #要素を取り出せる
if __name__ == "__main__":
#読み込み対象ファイル
path = 'data/test.csv'
#ファイルモード
mode = "r" #読み込み用
csv_read_test(path, mode)
読み込み対象ファイルの内容。
11,12,13,14
21,22,23,24
31,32,33,34
##ファイル全体を読み込む
open
したファイルオブジェクトに対して、csvライブラリのreader
メソッドを使う。reader
メソッドを使うと、データをcsv形式として識別し、読み込んでくれる。ただし、reader
メソッドの戻り値のタイプは、<class '_csv.reader'>
というイテレータ(iterator)プロトコルに対応したオブジェクトなので、for
文を使いすべての行をlistに格納して戻り値とする。
こうすると「JSON形式のデータを読み込む」と同じようにファイル全体を読み込んで戻り値とする書き方に統一できる。
なお、listへの格納では、リスト内包表記を使うとすっきりと書ける。
from csv import reader
def csv_read_test(path, mode):
"""
csvファイル全体を読み込み、戻り値をlist型とする
"""
with open(path, mode) as f:
_reader = reader(f)
data = [row for row in _reader] #リスト内包表記
""" リスト内包表記を使わないとこんな感じ
data = [] #空のlistを定義
for row in _reader:
data.append(row) #1行追加
"""
return(data)
if __name__ == "__main__":
#読み込み対象ファイル
path = 'data/test.csv'
#ファイルモード
mode = "r" #読み込み用
data = csv_read_test(path, mode)
print("Type of ""data"":{}".format(type(data))) #list型
print("---- All data ----")
print(data)
print("---- Row data ----")
for row in data:
print(row)
print("Type of ""element"":{}".format(type(row[0]))) #str型
print(row[0]) #要素を取り出せる
#参考
Python: テキストファイルの読み込み – read()、readlines()、readline()メソッド
【Python入門】JSON形式データの扱い方
PythonでCSVファイルを読み込み・書き込み(入力・出力)
#更新 2020-01-01
「csv形式のデータを読み込む」のコードの書き方が、「JSON形式のデータを読み込む」と非統一なのが悔しくて、同じような書き方になるよう検討し、Ver2を追記した。
#更新 2020-01-04
ファイル全体を読み込む場合と、ファイルから1行ずつ読み込む場合の違いが分かるよう、「ファイルから1行ずつ読み込む」を追記した。その際、学習者の手がかりとして「イテレータ」という言葉を使った説明を加えた。