HOWTO · Python
ValueError: list.remove(x): X Not in List エラーを Python で修正
このチュートリアルでは、Python で ValueError: list.remove(x): x not in list を修正する方法を説明します。
このページの内容
ValueError: list.remove(x): x not in list は、remove() が渡された値と等しい値を見つけられなかったことを意味します。確認後にリストが変更された、値が予想と異なる、または最初から値が存在しなかった可能性があります。list.remove(x) は値を指定して削除します。既知の位置にある項目を削除する場合は、del items[index] または items.pop(index) を使います。
list.remove(x) が ValueError を発生させる理由
remove() は1回の呼び出しで値を1つ受け取り、一致する項目のうち最初のものを削除します。リストに同じ値が複数ある場合、後の一致項目は残ります。そのため、同じ値をもう一度削除できるのは、等しい値がまだリストにある場合だけです。
次の例では、まず "computer" を削除し、続けて同じ値をもう一度削除します。2回目の呼び出し時にはリストにその値が残っていないため、エラーが発生します。リストもコード内で定義しているので、この例は単独で実行できます。
このセクションのコードと表示されるラベルや出力は英語のままです。
items = ["science", "maths", "computer", "english"]
items.remove("computer")
print(items)
最初の呼び出しの後、"computer" は items に含まれていません。そのため、もう一度 remove() を呼び出すと、メッセージ list.remove(x): x not in list とともに ValueError が発生します。次の例ではエラーを捕捉するため、スクリプトを終了させずに型とメッセージを表示できます。コードと出力はバイト一致のため変更されておらず、表示されるエラーメッセージは英語のままです。
items = ["science", "maths", "computer", "english"]
items.remove("computer")
try:
items.remove("computer")
except ValueError as error:
print(f"{type(error).__name__}: {error}")
このメソッドは、現在のリストを等価性に基づいて検索します。文字列では大文字・小文字や空白が重要です。"Computer" と "computer" は異なる値です。独自のオブジェクトでは、等価性はその __eq__ の実装に従います。項目がリストにあるように見えるのに削除に失敗する場合は、呼び出しの直前にリストを確認し、実際の値と型を渡した値と比較してください。その間に、先行する削除やフィルタリング、異なる入力によってリストが変化している可能性があります。
削除する前に項目が存在するか確認する
値がリストにない可能性がある場合は、remove() を呼び出す前に、その値が含まれているか確認します。in 演算子も等価性に基づいて比較するため、この確認では削除と同じ一致条件が使われます。このパターンを使うときは、リストと削除する値をあわせて定義してください。
このセクションのコードと表示されるラベルや出力は英語のままです。
items = ["science", "maths", "english"]
item = "computer"
if item in items:
items.remove(item)
print(items)
値が存在する場合、確認後の呼び出しで一致する項目のうち最初のものが削除されます。値が存在しない場合はブロックが実行されず、リストは変更されません。値がないことが想定内で、何もする必要がない場合に便利です。値がないことがプログラミング上の誤りを示すなら、そのままスキップすると原因が隠れる可能性があります。データを検証するか、リストを作成する箇所でエラーを処理してください。
所属確認と削除は別々の操作です。間に変更がなければ、通常の単一スレッドのコードでは、どちらも同じリストの状態を対象にします。確認と呼び出しの間に別の処理がリストを変更する可能性がある場合、確認だけでは削除の成功を保証できません。アクセスを調整するか、エラーが起きうる操作箇所で ValueError を処理してください。
複数のリスト項目を安全に削除する
存在が確認できている値を複数削除するには、それぞれの値に対して remove() を1回ずつ呼び出します。1回の呼び出しに複数の値をまとめて渡すことはできません。次の単独で実行できる例では、2つの値を順番に削除します。
このセクションのコードと表示されるラベルや出力は英語のままです。
items = ["science", "maths", "computer", "english"]
items.remove("maths")
items.remove("english")
print(items)
削除する値が複数ある場合は、それらをループで処理します。値が存在しない可能性があるなら、呼び出しごとに確認してください。
items = ["science", "maths", "computer", "english"]
requested = ["maths", "history", "english"]
for item in requested:
if item in items:
items.remove(item)
print(items)
所属確認をしないループでは、最初に存在しない値に遭遇した時点で ValueError が発生して処理が止まり、後続の値は処理されません。確認を加えた方法なら、存在しない値をスキップしながら残りの値を処理できます。どちらの方法も元のリストを変更し、各要求値につき一致する項目を1つだけ削除します。条件に一致する項目をすべて削除するのが目的なら、内包表記で新しいリストを作るか、リストをフィルタリングしてください。remove() を繰り返し呼び出す場合は、削除回数と一致条件を明確にする必要があります。
データの状態に合った方法を選びます。値が存在すると分かっている場合は直接呼び出し、値がないことが通常あり得る場合は所属確認を行い、値がないことを報告すべき場合は明示的にエラーを処理します。予期しないエラーが起きたときは、リストの現在の内容を確認してください。