概要
Pythonのcsv.DictReader
オブジェクトを利用していたら以下の二つのエラーに遭遇しました。
どちらも解決できたので、こちらで紹介します。
KeyError: 'XXXX'
ValueError: invalid literal for int() with base 10: 'XXXX'
修正前コード
import os
import csv
csv_directory ='./csv'
for filename in os.listdir(csv_directory):
if filename.endswith('.csv'):
csv_file_path = os.path.join(csv_directory, filename)
with open(csv_file_path, newline='', encoding='utf-8') as csvfile:
csv_reader = csv.DictReader(csvfile)
for row in csv_reader:
model = row['model']
pk = int(row['pk'])
# 略
エラー1の原因
上記で実施すると以下のエラーになりました。
model = row['model']
KeyError: 'model'
csv.DictReader
を使用してファイルを開く際に、ヘッダー行を指定していないため、エラーが発生しています。
明示的にfieldnames
パラメータを指定して、ヘッダーを設定してあげると、エラーがなくなりました。
エラー2の原因
エラー1を修正後に実行すると以下のエラーになりました。
pk = int(row['pk'])
ValueError: invalid literal for int() with base 10: 'pk'
これは、int()
関数が数値以外の文字列(上記では'pk'
という文字列)を数値として解釈しようとしたためエラーになりました。最初の行を読み飛ばさないと、それもデータ行として解釈され、その中にヘッダーであるはずの'pk'
という文字列がデータとして認識されてしまい、int()
によって変換しようとしてエラーが発生したのです。
修正後コード
上記2点を修正したらエラーが消えました。
修正後のコードは以下です。
import os
import csv
csv_directory ='./csv'
for filename in os.listdir(csv_directory):
if filename.endswith('.csv'):
csv_file_path = os.path.join(csv_directory, filename)
with open(csv_file_path, newline='', encoding='utf-8') as csvfile:
csv_reader = csv.DictReader(csvfile, fieldnames=['model', 'pk'])
next(csv_reader)
for row in csv_reader:
model = row['model']
pk = int(row['pk'])
# 略
ちなみに、os.listdir(csv_directory)
は、 指定されたディレクトリ内のファイルおよびディレクトリのリストを返します。