Skip to main content

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 type NoneType. 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:

  1. Identify the source: Trace back to determine why the variable is None when you expected a subscriptable type.
  2. 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.
  3. Check for None: If the variable can validly be None at times, use an if 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.