Skip to main content

How to Resolve Python "AttributeError: 'list' object attribute 'append'/'extend' is read-only

When working with Python lists, you might encounter the AttributeError: 'list' object attribute 'append' is read-only or a similar message for other list methods like extend. This error signifies a misunderstanding of how to use list methods. You are attempting to assign a value to the method name itself (treating it like a variable attribute) instead of calling the method using parentheses () to perform its action.

This guide explains why this error occurs and shows the correct way to call list methods like append and extend.

Understanding the Error: Attributes vs. Method Calls

In Python:

  • Attributes are like variables associated with an object, accessed using dot notation (my_object.attribute_name). You can often assign new values to attributes (my_object.attribute_name = new_value).
  • Methods are like functions associated with an object, also accessed using dot notation, but they perform an action. To execute the action, you must call the method using parentheses (my_object.method_name(arguments)).

The list methods like append, extend, sort, insert, etc., are built-in operations designed to modify the list. Python protects these built-in methods from being accidentally overwritten by direct assignment, hence the "read-only" error message when you try to assign to them.

Cause: Assigning to a Method Name Instead of Calling It

The error occurs because your code uses the assignment operator (=) with a method name on the left side, instead of using call parentheses () with arguments inside.

# Error Scenario for append()
my_list = ['a', 'b']
print(f"Original list: {my_list}")

try:
# ⛔️ AttributeError: 'list' object attribute 'append' is read-only
# Trying to assign 'c' TO the append attribute itself
my_list.append = 'c'
except AttributeError as e:
print(f"Error with append: {e}")


# Error Scenario for extend()
my_list2 = ['a', 'b']
print(f"\nOriginal list 2: {my_list2}")

try:
# ⛔️ AttributeError: 'list' object attribute 'extend' is read-only
# Trying to assign ['c', 'd'] TO the extend attribute itself
my_list2.extend = ['c', 'd']
except AttributeError as e:
print(f"Error with extend: {e}")

Output:

Original list: ['a', 'b']
Error with append: 'list' object attribute 'append' is read-only

Original list 2: ['a', 'b']
Error with extend: 'list' object attribute 'extend' is read-only

Python interprets my_list.append = 'c' as an attempt to replace the built-in append method with the string 'c', which is not allowed for these read-only method attributes.

Solution: Use Call Parentheses ()

To fix the error, use the correct syntax for calling a method: place parentheses () after the method name and put any required arguments inside the parentheses.

Correctly Calling list.append()

The append() method takes one argument: the item to add to the end of the list.

my_list = ['a', 'b']
print(f"Original list: {my_list}")

# ✅ Call the append() method with the item 'c' inside parentheses
my_list.append('c')
print(f"After append('c'): {my_list}") # Output: ['a', 'b', 'c']

# Call it again
my_list.append('d')
print(f"After append('d'): {my_list}") # Output: ['a', 'b', 'c', 'd']

Output:

Original list: ['a', 'b']
After append('c'): ['a', 'b', 'c']
After append('d'): ['a', 'b', 'c', 'd']

Correctly Calling list.extend()

The extend() method takes one argument: an iterable (like another list, tuple, or string) whose elements will be added individually to the end of the list.

my_list = ['a', 'b']
items_to_add = ['c', 'd', 'e']
print(f"Original list: {my_list}")
print(f"Items to add: {items_to_add}")

# ✅ Call the extend() method with the iterable inside parentheses
my_list.extend(items_to_add)
print(f"After extend(items_to_add): {my_list}")

# Example extending with a tuple
my_list.extend(('f', 'g'))
print(f"After extend(('f', 'g')): {my_list}")

Output:

Original list: ['a', 'b']
Items to add: ['c', 'd', 'e']
After extend(items_to_add): ['a', 'b', 'c', 'd', 'e']
After extend(('f', 'g')): ['a', 'b', 'c', 'd', 'e', 'f', 'g']

Reminder: Modifying List Elements by Index

If your goal was not to add an element but to change an existing element at a specific position, you should use index assignment with square brackets [], not append or dot notation.

my_list = ['apple', 'banana', 'cherry']
print(f"Original list: {my_list}")

# ✅ Change the element at index 1 using square brackets
index_to_change = 1
new_value = 'blueberry'
my_list[index_to_change] = new_value

print(f"After changing index {index_to_change}: {my_list}")
# Output: After changing index 1: ['apple', 'blueberry', 'cherry']

Output:

Original list: ['apple', 'banana', 'cherry']
After changing index 1: ['apple', 'blueberry', 'cherry']

How append() and extend() Work

  • my_list.append(item): Adds a single item as one element to the end of my_list. Modifies the list in-place and returns None.
  • my_list.extend(iterable): Adds each element from the iterable individually to the end of my_list. Modifies the list in-place and returns None.

Because they modify the list in-place and return None, you generally don't assign the result of these calls to a variable:

my_list = ['x']
# Incorrect assignment (result_append will be None)
# result_append = my_list.append('y')

# Correct: Just call the method
my_list.append('y') # my_list is now ['x', 'y']

Conclusion

The AttributeError: 'list' object attribute 'X' is read-only (where X is a method like append or extend) occurs when you mistakenly try to assign a value to a list method name (my_list.append = ...) instead of calling the method (my_list.append(...)).

The solution is to use the correct method call syntax:

  • Place parentheses () after the method name.
  • Provide the required arguments inside the parentheses.
# Incorrect:
# my_list.append = item
# my_list.extend = other_list

# Correct:
my_list.append(item)
my_list.extend(other_list)

Understanding the difference between accessing/assigning attributes and calling methods is fundamental to avoiding this error.