How to Resolve Python "TypeError: 'NoneType' object is not subscriptable"
The TypeError: 'NoneType' object is not subscriptable
is a frequent error in Python that signals an attempt to access an element by index or key using square brackets ([]
) on a variable that currently holds the value None
. Python's None
represents the absence of a value and is not a sequence or mapping, meaning it doesn't support subscripting.
This guide explains the common reasons why a variable might hold None
and provides clear solutions to prevent or handle this error.
Understanding the Error: Subscriptable Objects vs. None
- Subscriptable Objects: These are containers that allow accessing elements using square brackets (
[]
). They implement the__getitem__
method. Common examples include:list
(by integer index)tuple
(by integer index)str
(by integer index)dict
(by key)
None
: A special singleton object representing nothingness or the absence of a value. It's of typeNoneType
. It is not a container and cannot be indexed or sliced using[]
.
The TypeError
occurs because you applied the subscripting operation ([]
) to None
, which doesn't support it.
The Cause: Using []
on a None
Value
The error is triggered when the variable before the square brackets (variable[...]
) holds the value None
at the time of access.
# Error Scenario
variable_holding_none = None
print(f"Variable type: {type(variable_holding_none)}") # Output: <class 'NoneType'>
try:
# ⛔️ TypeError: 'NoneType' object is not subscriptable
# Trying to access index 0 of None
value = variable_holding_none[0]
print(value)
except TypeError as e:
print(e)
try:
# ⛔️ TypeError: 'NoneType' object is not subscriptable
# Trying to access key 'key' of None
value = variable_holding_none['key']
print(value)
except TypeError as e:
print(e)
Common Sources of None
Values
Investigate why your variable holds None
when you expected a list, tuple, string, or dictionary.
Explicit Assignment (my_variable = None
)
The variable was directly assigned the None
value somewhere in the code.
Function Returning None
Implicitly (No return
)
A function defined without an explicit return
statement automatically returns None
.
def configure_settings():
print("Configuring...")
# No return statement here
settings = configure_settings() # settings is now None
print(f"Result of configure_settings(): {settings}")
try:
setting_value = settings['theme'] # ⛔️ Error: Accessing None['theme']
except TypeError as e:
print(f"Error: {e}")
Output:
ERROR!
Configuring...
Result of configure_settings(): None
Error: 'NoneType' object is not subscriptable
Assignment from Methods Returning None
(e.g., list.sort()
)
Many methods that modify objects in-place (like list.sort()
, list.reverse()
, list.append()
) return None
. Assigning the result of such a method call will store None
in your variable.
my_numbers = [30, 10, 20]
print(f"Original list: {my_numbers}") # Output: Original list: [30, 10, 20]
# Scenario: Assigning result of sort()
result_variable = my_numbers.sort() # my_numbers is sorted, but result_variable gets None
print(f"List after sort: {my_numbers}") # Output: List after sort: [10, 20, 30]
print(f"Result variable: {result_variable}") # Output: None
try:
first_sorted = result_variable[0] # ⛔️ Error: Accessing None[0]
except TypeError as e:
print(f"Error accessing result_variable: {e}")
Output:
Original list: [30, 10, 20]
List after sort: [10, 20, 30]
Result variable: None
Error accessing result_variable: 'NoneType' object is not subscriptable
Function Returning None
Conditionally
A function might only return a value (like a list) if a condition is met, implicitly returning None
otherwise.
def find_user(user_id, user_database):
if user_id in user_database:
return user_database[user_id] # Returns user dict if found
# Implicitly returns None if user_id not found
users = {'Anna': {'age': 23}, 'David': {'age': 26}}
found_user = find_user('charlie', users) # charlie not in users, function returns None
print(f"Result of find_user('charlie'): {found_user}") # Output: None
try:
user_age = found_user['age'] # ⛔️ Error: Accessing None['age']
except TypeError as e:
print(f"Error accessing user age: {e}")
Output:
Result of find_user('charlie'): None
Error accessing user age: 'NoneType' object is not subscriptable
Assigning Result of print()
The print()
function performs output but returns None
. Assigning its result stores None
.
output_result = print("Hello World") # Prints "Hello World"
print(f"Variable output_result: {output_result}") # Output: None
try:
first_char = output_result[0] # ⛔️ Error: Accessing None[0]
except TypeError as e:
print(f"Error accessing print result: {e}")
Output:
Hello World
Variable output_result: None
Error accessing print result: 'NoneType' object is not subscriptable
Solution 1: Ensure Variable Holds a Subscriptable Type (Fix the Source)
The most robust solution is to fix the logic that results in None
being assigned when a subscriptable type is expected.
Correct Initialization
Initialize variables intended to be lists or dicts with []
or {}
respectively, not None
, if they will be accessed via subscripting later.
Ensure Functions Return Appropriate Types
Modify functions to always return a value of the expected type (e.g., return an empty list []
or empty dict {}
instead of implicitly returning None
if no result is found).
# ✅ Fixed function returns empty list if user not found
def find_user_safe(user_id, user_database):
if user_id in user_database:
return user_database[user_id]
else:
return {} # Return empty dict instead of None
users = {'Anna': {'age': 23}, 'David': {'age': 26}}
found_user = find_user_safe('charlie', users)
print(f"Result of find_user_safe('charlie'): {found_user}") # Output: {}
# Accessing now might give KeyError or default value, but not TypeError
user_age = found_user.get('age', 'N/A') # Safely access using .get()
print(f"User age (safe access): {user_age}") # Output: N/A
Output:
Result of find_user_safe('charlie'): {}
User age (safe access): N/A
Avoid Assigning Results of In-Place Methods
When using methods like list.sort()
, work with the original list variable after the method call, not the None
result returned by the method.
my_numbers = [30, 10, 20]
# ✅ Call sort() directly on the list
my_numbers.sort()
# ✅ Access the modified list using its original name
first_sorted = my_numbers[0]
print(f"First element after sort: {first_sorted}") # Output: First element after sort: 10
Output:
First element after sort: 10
Solution 2: Check if Variable is None
Before Subscripting
If it's possible and valid for your variable to sometimes hold None
, you must check for this possibility before attempting to access it with square brackets.
def get_optional_data():
# This function might return a list or None
import random
return ['data', 'point'] if random.choice([True, False]) else None
data = get_optional_data()
print(f"Data received: {data} (Type: {type(data)})")
first_item = None # Initialize with a default
# ✅ Check if data is not None before accessing
if data is not None:
try:
first_item = data[0]
print(f"First item found: {first_item}")
except IndexError:
print("Data is not None, but is empty or index is invalid.")
except TypeError:
# Should not happen if 'data is not None' check passes for list/str/tuple/dict
print("Data is not None, but still not subscriptable?")
else:
print("Data is None, cannot access element.")
# Handle the None case (e.g., use the default 'None' for first_item)
print(f"Final first_item: {first_item}")
Output:
Data received: None (Type: <class 'NoneType'>)
Data is None, cannot access element.
Final first_item: None
This prevents the TypeError
by guarding the subscript access.
Conclusion
The TypeError: 'NoneType' object is not subscriptable
arises when you use square bracket notation (variable[...]
) on a variable that holds the None
value. None
represents nothing and cannot be indexed or keyed like lists, tuples, strings, or dictionaries.
To fix this error:
- Identify the source: Trace back to determine why the variable is
None
when you expected a subscriptable type. - Correct the source: Modify the code (initialize properly with
[]
or{}
, ensure functions return subscriptable types, don't assign results of in-place methods like.sort()
) so the variable holds the correct type. - Check for
None
: If the variable can validly beNone
at times, use anif variable is not None:
check before attempting to subscript it.
Ensuring your variable holds a list, tuple, string, or dictionary before using square brackets []
on it is essential to avoid this TypeError
.