数字を入力してもらうプログラムを作ったのに、ValueError: invalid literal for int() with base 10 と出て止まってしまった。Pythonを学び始めたころ、こんな場面に出会ったことはありませんか?
コードを見直しても、どこが悪いのかすぐにはわかりませんよね。実はValueErrorは、コードの書き方よりも、流れてきた値のほうに原因があることが多いエラーです。
この記事では、ValueErrorの意味とメッセージの読み方から、よくある原因と直し方までを順番に見ていきます。後半では、ValueErrorに強いコードの書き方も紹介します。
サンプルの実行結果は、手元のPython 3.11、3.12、3.13で確認したものです。この記事で紹介するメッセージは、3つのバージョンで同じ表示でした。
ValueErrorとはどんなエラーなのか¶
まずは、ValueErrorが何を知らせているのかを押さえておきましょう。ひとことで言うと、型は正しいのに値の中身が受け付けられないときに出るエラーです。
Pythonの公式ドキュメントでは、正しい型だが不適切な値を持つ引数を受け取ったときに送出される、と説明されています。IndexErrorのように、もっと具体的な例外で表せる場合はそちらが使われます。
たとえばint()は、文字列を受け取って整数に変換する関数です。"42"なら問題なく変換できますが、"abc"を渡すと数字として読めないので、ValueErrorになります。
どちらも同じ文字列という型なのに、結果が分かれるのがポイントです。型変換の基本をおさらいしたい方は、こちらの記事が役に立ちます。 【関連記事】Pythonの型変換とは?int()・float()・str()・bool()の使い方と、int("3.5")がエラーになる落とし穴
TypeErrorとの見分け方¶
ValueErrorといちばん混同されやすいのが、TypeErrorです。迷ったときは、型そのものが違うのか、型は合っていて中身が違うのかで考えると整理できます。
2つの違いを表にまとめると、次のようになります。
| エラー | 何がおかしいか | 例 |
|---|---|---|
| TypeError | 値の型がそもそも合っていない | int(None)、"年齢" + 20 |
| ValueError | 型は合っているが値の中身が合わない | int("abc")、math.sqrt(-1) |
int(None)は、Noneという型をint()が受け付けないのでTypeErrorです。一方でint("abc")は、文字列という型は受け付けたうえで、中身が数字ではないと判断されてValueErrorになります。
TypeErrorのくわしい原因と直し方は、前回の記事で解説しています。あわせて読むと、2つの違いがよりはっきりするはずです。 【関連記事】PythonのTypeErrorとは?can only concatenate strやobject is not callableの原因と直し方
エラーメッセージの読み方¶
次に、メッセージのどこを見ればよいのかを確認しましょう。冒頭の例を、実際のコードで再現してみます。
count = int("abc")
これを実行すると、最後の行に次のメッセージが表示されます。
ValueError: invalid literal for int() with base 10: 'abc'
literalは、ここではプログラムに書かれた値の表記という意味です。つまり、10進数の整数としては読めない表記です、int()では変換できません、と教えてくれています。
注目してほしいのは、コロンのあとに実際に渡された値が表示されている点です。ValueErrorのメッセージの多くは、問題を起こした値そのものを見せてくれます。
まずはその値が自分の想定どおりかを確かめましょう。空文字の '' や、末尾に余計な文字がついた '10円' が表示されていれば、それが原因です。
エラーが起きた行を探すときは、メッセージより上に表示されるtracebackを読みます。読み方に自信がない方は、こちらで確認しておきましょう。 【関連記事】Pythonのエラー文はどこを読めばいい?初心者向けtracebackの見方
ValueErrorのよくある原因一覧¶
ValueErrorにもいくつかの定番パターンがあります。エラーが出たら、まずは次の表からメッセージの似ているものを探してみてください。
| メッセージ | 主な原因 |
|---|---|
| invalid literal for int() with base 10: 'abc' | 整数として読めない文字列をint()に渡した |
| could not convert string to float: 'abc' | 数値として読めない文字列をfloat()に渡した |
| too many values to unpack (expected 2) | 受け取る変数より値の数が多い |
| not enough values to unpack (expected 3, got 2) | 受け取る変数より値の数が少ない |
| 5 is not in list | リストにない値をindex()で探した |
| list.remove(x): x not in list | リストにない値をremove()で消そうとした |
| day is out of range for month | 存在しない日付を作ろうとした |
| math domain error | 数学関数に計算できない値を渡した |
こうして並べると、どれも値の中身が条件に合っていないという共通点が見えてきます。ここからは、とくに出会う機会の多いものを順番に見ていきます。
原因1 int()やfloat()に変換できない文字列を渡した¶
もっとも多いのが、この変換の失敗です。input()で受け取った値や、CSVファイルから読み込んだ値は、どれも文字列として届きます。
その文字列に数字以外が混ざっていると、int()は変換をあきらめます。全角の数字は変換できますが、10円のような単位つきや、カンマ区切りの1,000は失敗します。
意外なのは、前後の空白や改行は許されることです。int(" 42\n")は42になりますが、数字の間に空白が入った"1 000"はエラーになります。
なお、Python 3.6からは"1_000"のようにアンダースコアで桁を区切った文字列も変換できます。ただし実際のデータで見かけるのはカンマ区切りのほうが多いので、replace()で取り除いてから変換するのが定番です。
int("3.5")が失敗する理由¶
初心者がとくに戸惑うのが、int("3.5")がエラーになることです。小数を切り捨ててくれそうに思えますが、int()は文字列を整数の表記として読もうとするので、小数点を含むとそこで止まります。
小数を含む文字列を整数にしたいときは、いったんfloat()を通すのが近道です。int(float("3.5"))と書けば、3になります。
ここで知っておきたいのが、int()に数値の3.5を渡した場合は切り捨てになることです。文字列のときと数値のときで動きが違うので、変換の前に型を確かめるクセをつけておきましょう。
私は10年ほどエンジニアとして開発に関わってきましたが、このエラーにいちばん悩まされたのは売上CSVの取り込みでした。ほとんどの行は数字なのに、数千行に1行だけ空欄が混ざっていて、int('')で夜間のバッチが止まったことがあります。
原因2 アンパックで値の数が合わない¶
次は、変数への分解で起きるパターンです。a, b = [1, 2]のように、複数の値をまとめて変数に受け取る書き方をアンパックと呼びます。
便利な書き方ですが、左側の変数の数と右側の値の数が合わないとValueErrorになります。メッセージを見れば、どちらが多いのかがわかります。
a, b = [1, 2, 3]
# ValueError: too many values to unpack (expected 2)
x, y, z = [1, 2]
# ValueError: not enough values to unpack (expected 3, got 2)
expected 2は、受け取る側が2つを期待していたという意味です。got 2は、実際には2つしか届かなかったことを表しています。
よくあるのは、split()で区切った結果を受け取る場面です。name, age = line.split(",")と書いた場合、区切り文字のカンマが1つでも多いと too many values になります。
値の数が決まっていないときは、を使って残りをまとめて受け取れます。first, rest = [1, 2, 3]と書けば、restには[2, 3]が入ります。
辞書をfor文で回したときの落とし穴¶
アンパックのエラーは、辞書をfor文で回すときにもよく起こります。for k, v in scores: のように書くと、not enough values to unpack になることがあります。
辞書をそのままfor文で回すと、取り出されるのはキーだけだからです。キーが1文字の文字列なら got 1 になり、3文字以上なら too many values と表示されます。ちょうど2文字のキーだとエラーにならず、1文字ずつkとvに分かれてしまうので余計に気づきにくいのです。
キーと値をセットで取り出したいときは、for k, v in scores.items(): と書きましょう。items()を付けるだけで、エラーが消えて意図どおりに動きます。
原因3 リストにない値をindex()やremove()で探した¶
リストのindex()とremove()も、ValueErrorの常連です。どちらも、探している値がリストの中に見つからないとValueErrorを送出します。
index()は値の位置を返すメソッドで、見つからなければ 5 is not in list のようなメッセージになります。remove()は最初に見つかった値を消すメソッドで、なければ list.remove(x): x not in list です。
文字列のindex()も同じで、見つからないと substring not found と表示されます。文字列の場合は、見つからないと-1を返すfind()を使う手もあります。
いちばんシンプルな対策は、in演算子で先に存在を確かめることです。if "りんご" in fruits: のように条件をつけてから呼び出せば、エラーにはなりません。
原因4 日付や数学関数に範囲外の値を渡した¶
最後は、値の範囲が決まっている関数に、範囲外の値を渡したケースです。代表的なのが、日付を扱うdatetimeモジュールです。
たとえばdatetime.date(2026, 2, 30)は、2月30日が存在しないので day is out of range for month になります。文字列から日付を作るstrptime()でも、形式が合わないと does not match format というValueErrorになります。
数学関数では、math.sqrt(-1)が math domain error になります。domainは定義域のことで、この関数では計算できない範囲の値ですという意味です。
日付の扱いについては、こちらの記事でくわしく紹介しています。うるう年や月末の扱いも含めて、まとめて確認しておくと安心です。 【関連記事】Pythonのdatetimeを完全攻略!日付の計算やタイムゾーンで迷わないために
ValueErrorに強いコードを書くには¶
ここまで見てきたように、ValueErrorは外から入ってくる値が原因になりがちです。ユーザーの入力やファイルの中身は、こちらで完全にはコントロールできません。
そこで役に立つのが、try-exceptでValueErrorを受け止める書き方です。Pythonには、先に試してから失敗を処理するという考え方が根づいています。
次の例は、年齢の入力を受け取って、正しい値が入るまで聞き直すプログラムです。変換の失敗と、範囲外の値の両方をValueErrorとして扱っています。
def parse_age(text):
age = int(text.strip())
if not 0 <= age <= 150:
raise ValueError(f"年齢は0〜150で入力してください: {age}")
return age
while True:
text = input("年齢を入力してください:")
try:
age = parse_age(text)
except ValueError as e:
print("入力をもう一度確認してください。", e)
continue
break
print(f"{age}歳ですね。登録しました。")
abcと入力すると invalid literal for int() のメッセージが表示され、200と入力すると自分で用意したメッセージが表示されます。どちらの場合も、プログラムは止まらずにもう一度入力を求めてくれます。
注目してほしいのは、parse_age()の中で自分からValueErrorを送出している点です。範囲外の値のように型は合っていても受け付けたくない値には、ValueErrorを使うのがPythonの慣習です。
try-exceptの書き方を基礎から確認したい方は、こちらの記事をどうぞ。exceptに例外の種類を書く理由もくわしく解説しています。 【関連記事】Pythonのtry・except・else・finallyとは?例外処理の基本の流れ
注意したいのは、try-exceptでエラーを握りつぶしてしまうことです。except ValueError: pass と書いて何も記録しないと、どのデータが悪かったのかがあとからわからなくなります。
実務では、失敗した行番号と値をログに残してから処理を続けるのが一般的です。先ほどの売上CSVの件以来、私は取り込めなかった行を別ファイルに書き出すようにしていて、原因の調査がずいぶん楽になりました。
まとめ¶
ValueErrorは、型は合っているのに値の中身が受け付けられないことを知らせるエラーです。メッセージには問題の値が表示されることが多いので、まずはコロンのあとの値を読むことが解決の近道になります。
最後に、この記事で紹介した原因と直し方を表で振り返っておきましょう。
| 原因 | 直し方 |
|---|---|
| 数字として読めない文字列を変換した | 空欄や単位、カンマを取り除く。小数はfloat()を通す |
| アンパックで値の数が合わない | split()の結果を確かめる。*restで残りを受け取る |
| 辞書をfor文で回した | items()を付けてキーと値を取り出す |
| リストにない値を探した | in演算子で先に存在を確かめる |
| 存在しない日付や範囲外の値を渡した | 入力値の範囲をチェックする |
ValueErrorに出会うのは、プログラムが外の世界のデータを扱い始めた証拠でもあります。最初は戸惑っても、パターンを知っていれば落ち着いて対処できるようになります。
今日の内容が、次にValueErrorを見かけたときの手がかりになればうれしいです。
ここまでお読みいただきありがとうございました。