エラーの解説
Pythonのint()関数が、10進数の整数として認識できない文字列に遭遇したときにこのエラーが発生します。翻訳の失敗のようなものだと考えてください。「apple」や「12.5」といった値を整数に変換しようとしていますが、Pythonは「42」や「1000」のような純粋な数字しか処理できないのです。
# このコードでエラーが発生します
number = int("10.5")
# 出力: ValueError: invalid literal for int() with base 10: '10.5'
コードが壊れる原因
データが常に完璧であることは稀です。主に以下の4つの状況でこのボトルネックに遭遇する可能性があります。
- **浮動小数点文字列:** 値が`"10.0"`であっても、小数点があると`int()`コンストラクタは混乱します。
- **書式設定文字:** 実際のデータには、カンマ(`"1,250"`)や通貨記号(`"$50"`)が含まれていることが多く、Pythonはこれらを自動的に無視できません。
- **空の入力:** CSVの空行や空のテキストボックスを読み取ると`""`(空文字)を受け取りますが、これは数値ではありません。
- **隠れた空白:** 文字列が`"100"`に見えても、実際には`"100\n"`や`" 100 "`であることがあります。
解決策1:小数の文字列(浮動小数点数)の処理
文字列が小数の場合、int()は即座に失敗します。Pythonの変換ロジックは、丸め処理による予期せぬデータ損失を防ぐために厳格に設計されています。これを修正するには、まず文字列をfloatに変換し、その後にそのfloatを整数にキャストします。
price_str = "45.99"
# この方法では小数が切り捨てられ、45が返されます
value = int(float(price_str))
print(value)
解決策2:不適切なデータに対してTry-Exceptブロックを使用する
外部APIから数千行のデータを処理する場合、すべての値を手動でチェックすることはできません。変換処理をtry-exceptブロックで囲むことで、「汚い」レコードに遭遇してもアプリケーションを停止させずに継続できます。
raw_data = ["23", "42", "unknown", "15"]
for item in raw_data:
try:
age = int(item)
print(f"処理済みの年齢: {age}")
except ValueError:
print(f"無効なエントリをスキップ: {item}")
continue
解決策3:空白と書式の削除
隠れた文字は、Pythonスクリプトにおける最も一般的な「静かなる暗殺者」です。ファイルのインポート時に入り込みやすい不可視の改行文字や先頭のスペースを削除するには、.strip()を使用します。
user_input = " 500 \n"
# 変換前に両端をクリーンアップ
clean_input = user_input.strip()
if clean_input:
result = int(clean_input)
print(result) # 出力: 500
解決策4:通貨記号とカンマのサニタイズ
Webサイトをスクレイピングしていると、"$1,250.00"のような価格文字列を取得することがあります。int()は0〜9の数字しか理解できないため、まず数値以外の余計な文字を取り除く必要があります。
# シナリオ:書式設定された価格をセントに変換する
raw_price = "$1,250.50"
# 記号とカンマを削除し、float経由で変換
clean_price = raw_price.replace("$", "").replace(",", "")
price_in_cents = int(float(clean_price) * 100)
print(price_in_cents) # 出力: 125050
解決策5:.isdigit()で検証する
正の整数のみを処理したいシンプルなスクリプトでは、.isdigit()が非常に便利です。これは真偽値を返すため、文字列が無効な場合は変換自体をスキップできます。
data = "123"
if data.isdigit():
number = int(data)
else:
# 負の数、小数、テキストをキャッチします
print("入力は有効な正の整数ではありません。")
本番環境におけるベストプラクティス
- **失敗をログに記録する:** 大規模なデータセットで変換が失敗した場合は、後でデータソースを修正できるように、問題のあった特定の文字列をログに記録してください。
- **デフォルト値:** 変換が失敗した場合のフォールバック値(`0`や`None`など)を常に決めておきましょう。
- **入力タイプ:** Webアプリを構築している場合は、HTML5の`type="number"`を使用して、そもそもユーザーが数値以外の文字列をPythonのバックエンドに送信できないようにします。

