The ValueError: invalid literal for int() with base 10: '...' is a frequent Python error encountered when using the int() function to convert a string to an integer. It signifies that the string provided to int() does not represent a valid whole number in base 10 (our standard decimal system) and therefore cannot be directly converted.
This guide explains the common reasons for this error – like non-digit characters, decimal points, or empty strings – and provides solutions for handling or cleaning the input string before conversion.
Understanding the Error: What int() Expects
The built-in int() function, when given a string argument, attempts to parse that string as an integer according to the specified base (which defaults to base 10). For base 10, a valid string must:
- Contain only digit characters (
0through9). - Optionally have a leading sign (
+or-). - Not contain decimal points (
.) or other non-digit characters (letters, symbols, spaces within the number). - Not be empty or contain only whitespace after stripping.
The ValueError occurs when the input string violates these rules. The part of the error message after the colon (: '...') shows the specific invalid literal (the string) that int() could not parse.
Cause 1: String Contains Non-Digit Characters
This includes letters, symbols, spaces within the digits, or other characters that aren't 0-9 (or a leading sign).
Error Scenario
string_with_letters = "12a3"
string_with_symbols = "1,000" # Comma is not a digit
string_with_spaces = "1 2 3"
try:
num = int(string_with_letters)
except ValueError as e:
print(e)
try:
num = int(string_with_symbols)
except ValueError as e:
print(e)
try:
num = int(string_with_spaces)
except ValueError as e:
print(e)Solution: Validate Input / Handle Errors (try...except)
Especially when dealing with user input or external data, you cannot guarantee the string will be valid. The most robust approach is to wrap the int() call in a try...except ValueError block.
user_input = input("Enter a whole number: ") # User might enter 'abc'
try:
number = int(user_input)
print(f"You entered the integer: {number}")
except ValueError:
print(f"Invalid input: '{user_input}' is not a valid whole number.")
number = 0 # Example fallbackSolution: Extract Digits Before Conversion (If Appropriate)
If you know the string might contain non-digits but you only want to convert the digits present, you can filter them out first. Use this cautiously, as it might not be appropriate for all inputs (e.g., "1a2b" becomes 12).
import re
mixed_string = "ID: 456-ABC"
digits_only = "".join(filter(str.isdigit, mixed_string))
print(f"Digits extracted: '{digits_only}'") # Output: '456'
if digits_only: # Check if any digits were found
number = int(digits_only)
print(f"Converted number: {number}") # Output: 456
else:
print("No digits found in string.")
match = re.search(r'\d+', mixed_string) # Find first sequence of digits
if match:
number_re = int(match.group(0))
print(f"First number found (regex): {number_re}") # Output: 456
else:
print("No number sequence found.")Cause 2: String Represents a Float (Contains Decimal Point)
The int() function cannot directly parse strings containing a decimal point (.), even if the fractional part is zero (like "5.0").
Error Scenario
float_string = "123.45"
zero_decimal_string = "5.0"
try:
num = int(float_string)
except ValueError as e:
print(e)
try:
num = int(zero_decimal_string)
except ValueError as e:
print(e)Solution: Convert to float() First, then int()
The standard way to handle this is to first convert the string to a float using float(), and then convert that float to an int. Converting a float to an int truncates (removes) the decimal part.
float_string = "123.45"
zero_decimal_string = "5.0"
try:
num_float = float(float_string) # Converts to 123.45
num_int = int(num_float) # Truncates to 123
print(f"'{float_string}' -> float: {num_float} -> int: {num_int}")
num_float_zero = float(zero_decimal_string) # Converts to 5.0
num_int_zero = int(num_float_zero) # Truncates to 5
print(f"'{zero_decimal_string}' -> float: {num_float_zero} -> int: {num_int_zero}")
except ValueError:
print("String is not a valid float.")Handling Rounding (Optional)
If you need standard rounding instead of truncation when converting from a float string:
import math
float_string = "123.78"
float_string_low = "123.12"
num_int_rounded = int(round(float(float_string)))
print(f"'{float_string}' rounded to int: {num_int_rounded}") # Output: 124
num_int_ceil = int(math.ceil(float(float_string)))
print(f"'{float_string}' ceiling to int: {num_int_ceil}") # Output: 124
num_int_floor = int(math.floor(float(float_string_low)))
print(f"'{float_string_low}' floor to int: {num_int_floor}") # Output: 123Cause 3: Empty or Whitespace-Only String
Passing an empty string ("") or a string containing only whitespace (" ") to int() will also cause a ValueError.
Error Scenario
empty_str = ""
space_str = " "
try:
num = int(empty_str)
except ValueError as e:
print(e)
try:
num = int(space_str)
except ValueError as e:
print(e)Solution: Check and Provide Default (e.g., or '0')
Use string stripping and the or operator to provide a default value (like '0') if the string is empty after stripping whitespace.
empty_str = ""
space_str = " "
num_empty = int(empty_str.strip() or '0')
print(f"Result for empty string: {num_empty}") # Output: Result for empty string: 0
num_space = int(space_str.strip() or '0')
print(f"Result for space string: {num_space}") # Output: Result for space string: 0
valid_str = " 123 "
num_valid = int(valid_str.strip() or '0')
print(f"Result for valid string: {num_valid}") # Output: Result for valid string: 123my_str.strip(): Removes leading/trailing whitespace.... or '0': Ifmy_str.strip()results in an empty string (which is falsy), the expression evaluates to'0'. Otherwise, it evaluates to the stripped string.
Solution: Use if Check Before Conversion
Explicitly check if the stripped string is non-empty.
maybe_empty = " "
number = 0 # Default
stripped = maybe_empty.strip()
if stripped: # Check if string is non-empty after stripping
try:
number = int(stripped)
print("Conversion successful.")
except ValueError:
print(f"Stripped string '{stripped}' is not a valid integer.")
else:
print("String is empty or contains only whitespace.") # This is executed
print(f"Final number: {number}")Best Practice: Use try...except ValueError
Because you often cannot guarantee the format of strings coming from external sources (user input, files, APIs), the most robust and Pythonic way to handle potential conversion errors is to always wrap int() calls in a try...except ValueError block when dealing with strings.
def safe_string_to_int(input_str, default=0):
"""Safely converts a string to an int, returning default on failure."""
try:
return int(input_str.strip())
except (ValueError, TypeError, AttributeError): # Catch errors if input is None, not string, or invalid format
print(f"Warning: Could not convert '{input_str}' to int. Returning default.")
return default
print(safe_string_to_int(" 123 ")) # Output: 123
print(safe_string_to_int("45a")) # Output: Warning... Returning default. -> 0
print(safe_string_to_int(" ")) # Output: Warning... Returning default. -> 0
print(safe_string_to_int(None)) # Output: Warning... Returning default. -> 0
print(safe_string_to_int("5.6")) # Output: Warning... Returning default. -> 0Output:
123
Warning: Could not convert '45a' to int. Returning default.
0
Warning: Could not convert ' ' to int. Returning default.
0
Warning: Could not convert 'None' to int. Returning default.
0
Warning: Could not convert '5.6' to int. Returning default.
0Conclusion
The ValueError: invalid literal for int() with base 10 occurs when you pass a string to int() that doesn't strictly represent a whole number in base 10.
Key solutions include:
- Handle Invalid Characters: Use
try...except ValueErrorto catch errors from strings containing non-digits (letters, symbols, internal spaces). Optionally pre-process strings to remove/extract digits if appropriate. - Handle Float Strings: Convert float-like strings (e.g.,
"123.45") tofloat()first, then toint()(which truncates). Useround(),math.ceil(), ormath.floor()afterfloat()if specific rounding is needed. - Handle Empty/Whitespace Strings: Use
.strip()combined with theor '0'fallback or anifcheck before callingint().
Using try...except ValueError is the most reliable way to handle potentially invalid string inputs before integer conversion.