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.