ValueError appears when the value has the right general type but still cannot be used the way Python expects. Conversion and unpacking problems usually land here because the shape or contents of the value are wrong.
A useful explanation should separate type problems from value problems, then show how parsers, casts, and unpacking rules reject bad content even when the object type itself is acceptable.
The key lesson is how to validate the value before conversion, choose a default when the input is optional, and report the bad data clearly when the value must be rejected.
A ValueError occurs in Python when a function receives an argument of the correct type but with an inappropriate value. For example, calling int("abc") passes a string (correct type) but the value "abc" cannot be converted to an integer. This is distinct from TypeError, which is about the wrong type entirely.
# Bad conversion: abc is not an integer literal
user_input = "abc"
number = int(user_input) # ValueError: invalid literal for int() with base 10: 'abc'
# Guarded conversion: catch invalid input
user_input = "abc"
try:
number = int(user_input)
except ValueError:
print(f"'{user_input}' is not a valid integer")
number = 0
The most common ValueError - trying to convert user input or data from a file/API to an integer when the string contains non-numeric characters. Always validate or use try/except when converting user-provided strings.
When unpacking a sequence into variables, the number of variables must match the number of elements. If there are more or fewer elements than expected, Python raises a ValueError.
When using Python's Enum class or functions that accept a limited set of valid values, passing an invalid value raises a ValueError. This is intentional - it enforces valid input.
The datetime.strptime() function raises a ValueError if the string does not match the specified format. This is common when parsing dates from user input or external data sources.
age = input("Enter your age: ") # User types "twenty"
age_int = int(age) # ValueError: invalid literal for int() with base 10: 'twenty'
def get_age():
while True:
age = input("Enter your age: ")
try:
return int(age)
except ValueError:
print(f"'{age}' is not a valid number. Please try again.")
age = get_age()
print(f"Your age is: {age}")
data = "Alice,30,Engineer,New York"
name, age = data.split(",") # ValueError: too many values to unpack (expected 2)
data = "Alice,30,Engineer,New York"
# Use * to capture remaining values
name, age, *rest = data.split(",")
print(name) # "Alice"
print(age) # "30"
print(rest) # ["Engineer", "New York"]
# Or unpack all expected fields
name, age, job, city = data.split(",") # Exact match
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
color = Color("YELLOW") # ValueError: 'YELLOW' is not a valid Color
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
# Validate before creating
def get_color(name):
try:
return Color[name.upper()]
except KeyError:
print(f"'{name}' is not a valid color. Choose: {[c.name for c in Color]}")
return None
color = get_color("RED") # Color.RED
color = get_color("YELLOW") # Prints error, returns None
from datetime import datetime
date_str = "2024/01/15"
date = datetime.strptime(date_str, "%d-%m-%Y") # ValueError: time data '2024/01/15' does not match format '%d-%m-%Y'
from datetime import datetime
date_str = "2024/01/15"
# Match the format to the actual string
date = datetime.strptime(date_str, "%Y/%m/%d") # Correct format
print(date) # 2024-01-15 00:00:00
# Handle multiple formats
formats = ["%Y/%m/%d", "%d-%m-%Y", "%Y-%m-%d"]
for fmt in formats:
try:
date = datetime.strptime(date_str, fmt)
break
except ValueError:
continue
TypeError is about the wrong type (e.g., passing a list where a string is expected). ValueError is about the right type but wrong value (e.g., int("abc") - correct type str, but invalid value for int conversion).
Wrap the conversion in try/except: try: n = int(s) except ValueError: n = 0. Alternatively, use str.isdigit() to check first, though this does not handle negative numbers or floats.
It means the right side of the assignment has more elements than the left side has variables. Use * to capture extra values: a, b, *rest = [1, 2, 3, 4].
Explore 500+ free tutorials across 20+ languages and frameworks.