Python errors / ValueError

ValueError in Python

The value has the right type but one Python can't use, like the text "12.50" given to int().

ValueError: invalid literal for int() with base 10: 'abc'

Check these first

  1. What's in the text? int() wants a whole number and nothing else: no decimal point, letters or spaces, and not empty text.
  2. Count both sides. a, b = values needs exactly two values on the right.
  3. Check before you use it. if x in items: before items.remove(x) or items.index(x).

Causes and fixes

1 Text that isn't a number

int() reads whole numbers only. Use float() for decimals, and .strip() to remove spaces around typed input.

Broken
price = "12.50"
print(int(price))
ValueError: invalid literal for int() with base 10: '12.50'
Fixed
price = "12.50"
print(float(price))
12.5

2 Unpacking the wrong number of values

a, b = values gives each name one value, so there have to be as many names as values.

Broken
name, age = ["Ada", 36, "London"]
print(name, age)
ValueError: too many values to unpack (expected 2)
Fixed
name, age, city = ["Ada", 36, "London"]
print(name, age, city)
Ada 36 London

3 An item that isn't in the list

remove() and index() need the item to be in the list. Check with in first.

Broken
fruits = ["apple", "pear"]
fruits.remove("banana")
print(fruits)
ValueError: list.remove(x): x not in list
Fixed
fruits = ["apple", "pear"]
if "banana" in fruits:
    fruits.remove("banana")
print(fruits)
['apple', 'pear']

4 Maths that has no answer

math.sqrt() of a negative number, or math.log() of 0, has no answer. Check the value first.

Broken
import math
x = -4
print(math.sqrt(x))
ValueError: math domain error
Fixed
import math
x = -4
if x >= 0:
    print(math.sqrt(x))
else:
    print("No square root for", x)
No square root for -4

Other messages

More messages ValueError can show. Open yours for what it means and how to fix it.

max() iterable argument is empty

max() and min() need at least one value. Check the list first, or give a default for an empty one.

Broken
scores = []
print(max(scores))
ValueError: max() iterable argument is empty
Fixed
scores = []
print(max(scores, default=0))
0
substring not found

.index() fails when the text isn't there. .find() gives -1 instead, and in says whether it's there at all.

Broken
email = "ada.example.com"
at = email.index("@")
print(at)
ValueError: substring not found
Fixed
email = "ada.example.com"
at = email.find("@")
print(at)
-1
I/O operation on closed file.

A file opened with with closes when its indented block ends. Read or write it inside the block.

Broken
with open("notes.txt", "w") as f:
    f.write("first\n")
f.write("second\n")
print("Saved")
ValueError: I/O operation on closed file.
Fixed
with open("notes.txt", "w") as f:
    f.write("first\n")
    f.write("second\n")
print("Saved")
Saved
time data '25/12/2024' does not match format '%Y-%m-%d'

strptime() needs the text to follow the format exactly. Write the format the way the date is written: %d/%m/%Y for 25/12/2024, %Y-%m-%d for 2024-12-25.

Broken
from datetime import datetime
day = datetime.strptime("25/12/2024", "%Y-%m-%d")
print(day.year)
ValueError: time data '25/12/2024' does not match format '%Y-%m-%d'
Fixed
from datetime import datetime
day = datetime.strptime("25/12/2024", "%d/%m/%Y")
print(day.year)
2024
Unknown format code 'd' for object of type 'float'

:d formats whole numbers only. For a number with decimals, use :.2f (two decimals) or :.0f (none).

Broken
price = 9.5
print(f"Price: {price:d}")
ValueError: Unknown format code 'd' for object of type 'float'
Fixed
price = 9.5
print(f"Price: {price:.2f}")
Price: 9.50
empty range in randrange(5, 2)

random.randint(a, b) needs the smaller number first: random.randint(1, 5), not random.randint(5, 1). With a range worked out in the program, check that it isn't empty: randint(1, 0) fails the same way.

The truth value of an array with more than one element is ambiguous

An if, and or or needs one True or False, but a numpy array or a pandas column holds one for each item. Say which you mean: (a > 2).any() for at least one, (a > 2).all() for every one. Between conditions on a whole array, use & and | with brackets: (a > 2) & (a < 9).

Still stuck?