If you're working with Python, you've likely encountered the TypeError: 'int' object is not subscriptable
. This is a common error, especially for beginners or when dealing with dynamic data. It fundamentally signals a misunderstanding between what your code expects a variable to be and what it actually is.
What Does "'int' object is not subscriptable" Mean?
Let's break down the terms:
int
: This refers to the integer data type in Python, which represents whole numbers (e.g., 5, -10, 0).- Subscriptable: An object is "subscriptable" if you can access its internal items using square brackets []. Think of containers or sequences like lists (
my_list[0])
, tuples (my_tuple[1]
), strings (my_string[2]
), and dictionaries (my_dict['key']
). These objects hold multiple elements or key-value pairs that can be "subscribed" or accessed via an index or key. - Not Subscriptable: The error message tells you that integers (
int
) do not support this[]
access method.
Why isn't an integer subscriptable? An integer represents a single, indivisible numerical value. It doesn't contain other items. Trying to access the "first element" of the number 5 (like 5[0]
) doesn't make sense conceptually in Python, hence the TypeError
. You're treating a single value as if it were a sequence.
Common Scenarios Leading to the Error
This error typically arises when you attempt indexing or slicing on a variable that you thought was a list, tuple, string, or dictionary, but which actually holds an integer at that moment. Here are a couple of common ways this happens:
-
Accidental Variable Reassignment: You might have a variable that initially holds a subscriptable type (like a list) but later gets unintentionally overwritten with an integer.
# Initially, the variable is expected to be a list data = [10, 20, 30] print(f"Initial data type: {type(data)}") # Later in the code, perhaps in a loop or conditional block... # Mistake: data is accidentally overwritten with an integer data = 100 print(f"Data type after reassignment: {type(data)}") # Attempting to index the variable, now an integer try: element = data[0] print(element) except TypeError as e: print(f"Error: {e}")
Initial data type: <class 'list'> Data type after reassignment: <class 'int'> Error: 'int' object is not subscriptable
-
Incorrect Function Return Value: A function might be designed or expected to return a sequence (like a list or tuple), but due to certain conditions or a bug, it returns an integer instead. Any subsequent attempt to index this return value will result in the error.
def get_user_ids(active_only): """ Intended to return a list of user IDs. Mistakenly returns count (an int) if active_only is False. """ all_users = [101, 102, 103, 104, 105] active_users = [101, 103, 105] if active_only: return active_users # Returns a list (Correct) else: # Bug: Should return all_users list, but returns its length instead # return all_users return len(all_users) # Returns an integer (Incorrect) # Call the function requesting all users (hitting the bug) user_data = get_user_ids(False) print(f"Received data type: {type(user_data)}, Value: {user_data}") # Attempting to index the result, which is an integer try: first_user_id = user_data[0] print(f"First user ID: {first_user_id}") except TypeError as e: print(f"Error: {e}")
Received data type: <class 'int'>, Value: 5 Error: 'int' object is not subscriptable
How to Fix and Prevent the Error
Resolving this TypeError
involves ensuring that you only attempt subscripting operations on appropriate data types. Here are several strategies:
-
Check the Variable Type Before Subscripting: Use
isinstance()
to verify that the variable holds a list, tuple, string, or other subscriptable type before trying to access elements with[]
.def get_data_from_somewhere(): # This function might return different types based on conditions # For demonstration, let's make it return an integer sometimes import random if random.random() > 0.5: return [100, 200, 300] else: return 42 # Returns an integer maybe_a_list = get_data_from_somewhere() print(f"Received: {maybe_a_list} (Type: {type(maybe_a_list)})") if isinstance(maybe_a_list, (list, tuple, str)): # It's safe to subscript now if len(maybe_a_list) > 0: first_element = maybe_a_list[0] print(f"First element: {first_element}") else: print("The sequence is empty.") elif isinstance(maybe_a_list, int): print(f"Warning: Expected a sequence, but received an integer: {maybe_a_list}. Cannot subscript.") # Handle the integer case appropriately - maybe use the value directly? else: print(f"Warning: Received unexpected type: {type(maybe_a_list)}. Cannot subscript.") # Handle other potential types
Example Output (if integer is returned):
Received: 42 (Type: <class 'int'>) Warning: Expected a sequence, but received an integer: 42. Cannot subscript.
Example Output (if list is returned):
Received: [100, 200, 300] (Type: <class 'list'>) First element: 100
-
Ensure Functions Return Expected Types: Carefully review the logic within your functions, especially those with conditional (
if/else
) paths.- Use Type Hinting: Add type hints to your function signatures (e.g.,
def get_ids() -> list:
) to make expected return types explicit. Tools like [MyPy](https://mypy-lang.org/ "MyPy") can then statically check your code. - Write Docstrings: Document the expected parameter types and return types/values in the function's docstring.
- Add Unit Tests: Create tests that specifically check the function's return type under various input conditions.
(See the function example in the "Common Scenarios" section for code demonstrating this problem).
- Use Type Hinting: Add type hints to your function signatures (e.g.,
-
Debugging and Tracing: If you're unsure where the integer value is coming from:
- Print Statements: Insert
print()
statements just before the line causing the error to inspect the variable's type and value:# ... preceding code ... my_var = function_that_might_return_int() # Add this debug print before the line that might fail: print(f"DEBUG: Variable 'my_var' - Type: {type(my_var)}, Value: {my_var}") # The line below might cause the 'int is not subscriptable' error try: value = my_var[0] except TypeError: print("Caught the TypeError!") # ... rest of the code ...
- Use a Debugger: Step through your code using Python's built-in debugger (
pdb
) or the debugger integrated into your IDE (like VS Code, PyCharm). This allows you to inspect variable states at each step of execution. - Error Tracking Tools: For more complex applications or errors occurring in production, manual debugging can be difficult. Tools like [Rollbar](https://rollbar.com/platforms/python-error-tracking/ "Rollbar") automatically capture errors, including the traceback and variable states leading up to the
TypeError
, making it much faster to pinpoint the cause.
- Print Statements: Insert
-
Convert to a Subscriptable Type (If Appropriate): Sometimes, you might intentionally want to access the digits of a number. An integer itself isn't subscriptable, but you can convert it to a string first, which is.
account_number = 123456789 if isinstance(account_number, int): s_account_number = str(account_number) # Now s_account_number is a string '123456789' and is subscriptable first_digit = s_account_number[0] last_four_digits = s_account_number[-4:] print(f"First digit: {first_digit}") print(f"Last four digits: {last_four_digits}") else: print("Variable is not an integer.")
First digit: 1 Last four digits: 6789
The Bottom Line: Check Your Types
The TypeError: 'int' object is not subscriptable
error in Python is a direct result of trying to use index ([]
) access on an integer value, which doesn't support this operation. The key to fixing and preventing it lies in maintaining type consistency. Always ensure that variables you intend to subscript actually hold a subscriptable type (like a list, tuple, or string) at the time of access. Employ defensive coding practices like type checking (isinstance
), guarantee consistent function return types using hints and tests, and utilize debugging techniques to trace variable values.
Track, Analyze and Manage Errors With Rollbar
Managing errors and exceptions in your code is challenging. It can make deploying production code an unnerving experience. Being able to track, analyze, and manage errors in real-time can help you to proceed with more confidence. Rollbar automates error monitoring and triaging, making fixing Python errors easier than ever. Try it today!