Modify Python Lists
Learn how to modify Python lists with index assignment, concatenation, append(), extend(), del, and slice deletion.
A Python list is an ordered collection of values. A list is mutable, which means you can change it after creating it. You can replace elements, add elements, and delete elements.
This lesson assumes you know how to create a list and access an element by its index. For a refresher, see What Are Lists.
Lists Are Mutable
Changing an existing list is called mutating the list. The list object remains the same, but its contents change.
numbers = [10, 20, 30]
print(numbers)
numbers[1] = 99
print(numbers)
The output is:
[10, 20, 30]
[10, 99, 30]
The assignment changed numbers itself. By contrast, an expression such as list concatenation creates a new result list. Assigning that result to another variable does not change the original list.
numbers = [10, 20, 30]
combined = numbers + [40]
print(numbers)
print(combined)
[10, 20, 30]
[10, 20, 30, 40]
numbers and combined refer to different list objects. Methods such as append() and extend(), however, modify the existing list in place.
Change One List Element by Index
An index is the numeric position of an element. Python uses zero-based indexing, so index 0 identifies the first item, index 1 identifies the second item, and so on.
| Expression | Position affected | Explanation |
|---|---|---|
items[0] | First item | Indexes begin at zero. |
items[1] | Second item | The position one comes after index zero. |
items[:3] | Indexes 0, 1, and 2 | The stop index 3 is excluded. |
items[1:3] | Indexes 1 and 2 | The start is included and the stop is excluded. |
items[-1] | Last item | Negative indexing counts from the end. |
Index assignment replaces one element using this pattern:
list_name[index] = replacement
For example:
scores = [72, 85, 91]
scores[0] = 78
print(scores[0])
print(scores)
78
[78, 85, 91]
The replacement can have a different type from the original value. Python lists can contain mixed types.
values = [100, 200, 300]
values[1] = "two hundred"
print(values)
[100, 'two hundred', 300]
Add Items Through List Concatenation
Concatenation combines lists with the + operator. Both operands must be lists. The operation creates a new list and leaves the original operands unchanged.
numbers = [1, 2, 3]
extra_numbers = [4, 5]
combined = numbers + extra_numbers
print(numbers)
print(extra_numbers)
print(combined)
[1, 2, 3]
[4, 5]
[1, 2, 3, 4, 5]
To add more than one item with concatenation, put those items in a list on the right side of +.
items = ["pen", "paper"]
updated_items = items + ["ruler", "eraser"]
print(items)
print(updated_items)
A single non-list value cannot be concatenated directly with a list:
items = [1, 2]
# items + 3 # TypeError
Use items + [3] for a new list, or use items.append(3) to change the existing list.
Add One Item with append()
append() adds one object to the end of the same list. It changes the list in place.
numbers = [1, 2, 3]
print(numbers)
numbers.append(4)
print(numbers)
[1, 2, 3]
[1, 2, 3, 4]
Each call accepts one positional item. To add items individually, call the method repeatedly.
colors = ["red"]
colors.append("green")
colors.append("blue")
print(colors)
['red', 'green', 'blue']
Appending a list adds that list as one element. The result is a nested list, meaning a list stored inside another list.
items = [1, 2]
items.append([3, 4])
print(items)
[1, 2, [3, 4]]
items = [1, 2]
items.append(3)
print(items) # [1, 2, 3]
# Wrong:
# items = items.append(4)
# items is now None
Add Multiple Items with extend()
extend() adds each item from another iterable to the end of the existing list. An iterable is a value Python can process one item at a time; lists are common examples.
items = [1, 2]
more_items = [3, 4]
items.extend(more_items)
print(items)
[1, 2, 3, 4]
Compare append() and extend():
| Method call | Input | List result | Key behavior |
|---|---|---|---|
items.append(3) | One scalar value | [1, 2, 3] | Adds one object. |
items.append([3, 4]) | Another list | [1, 2, [3, 4]] | Adds the entire list as one nested element. |
items.extend([3, 4]) | Another list | [1, 2, 3, 4] | Adds each contained item. |
Like append(), extend() changes the original list and returns None. Call it on its own line.
Compare Common List Modification Operations
| Operation | Syntax pattern | Changes original list? | Result |
|---|---|---|---|
| Replace one item | items[index] = value | Yes | One element is replaced. |
| Combine lists | combined = items + extras | No | A new combined list is created. |
| Add one item | items.append(value) | Yes | One object is added at the end. |
| Add many items | items.extend(values) | Yes | Each item from the iterable is added. |
| Delete one item | del items[index] | Yes | One position is removed. |
| Delete a range | del items[start:stop] | Yes | A contiguous slice is removed. |
| Delete a range with assignment | items[start:stop] = [] | Yes | The selected slice is replaced by no elements. |
Delete One Item with del
The del statement removes an element when its position is known:
del list_name[index]
For example, deleting index 1 removes the second element. Later elements shift left to fill the gap.
numbers = [10, 20, 30, 40]
del numbers[1]
print(numbers)
print(numbers[1])
[10, 30, 40]
30
The value that was at index 2 moved to index 1. An invalid index raises IndexError.
numbers = [10, 20]
# del numbers[2] # IndexError: list assignment index out of range
Deleting by index is different from removing by value. del numbers[1] uses a position; a value-based operation such as numbers.remove(20) searches for a value.
Delete Multiple Items with Slice Deletion
A slice selects a range using start:stop. The start boundary is included, and the stop boundary is excluded. Use del with a slice to remove a contiguous range.
numbers = [10, 20, 30, 40]
del numbers[0:3]
print(numbers)
[40]
Because the stop index 3 is excluded, indexes 0, 1, and 2 were deleted. An omitted start has the same meaning as zero in this example:
numbers = [10, 20, 30, 40]
del numbers[:3]
print(numbers)
[40]
You can also replace a slice with an empty list. This is another way to delete the selected range, and it also changes the existing list.
numbers = [10, 20, 30, 40]
numbers[:3] = []
print(numbers)
[40]
Indexes, Slices, and Negative Positions
Assigning to one index replaces exactly one element. Assigning to a slice replaces the selected range and can change the list length.
items = ["a", "b", "c", "d"]
items[1] = "B"
print(items)
items[2:4] = ["C", "D", "E"]
print(items)
['a', 'B', 'c', 'd']
['a', 'B', 'C', 'D', 'E']
Negative indexes count from the end. Index -1 is the last item, so it can be used to modify or delete that item.
items = ["first", "middle", "last"]
items[-1] = "final"
print(items)
del items[-2]
print(items)
['first', 'middle', 'final']
['first', 'final']
Avoid Modifying a List While Iterating Over It
When a loop iterates over a list, it uses positions that can change as the list changes. Deleting an item during the loop can shift the next item into the current position, causing some values to be skipped.
numbers = [1, 2, 3, 4, 5, 6]
# Unsafe pattern: elements can be skipped.
for number in numbers:
if number % 2 == 0:
numbers.remove(number)
print(numbers)
A safer approach is to construct a new filtered list. This keeps the list being examined unchanged during iteration.
numbers = [1, 2, 3, 4, 5, 6]
odd_numbers = []
for number in numbers:
if number % 2 != 0:
odd_numbers.append(number)
print(numbers)
print(odd_numbers)
[1, 2, 3, 4, 5, 6]
[1, 3, 5]
Other possible strategies include iterating over a copy, such as numbers[:], or iterating backward when deletion by position is appropriate. Building a new list is often the clearest choice.
Troubleshooting List Modifications
IndexErrorwhen replacing or deleting: The index does not exist in the current list. Remember that the first index is0, and inspectlen(items)before using a position.TypeErrorwith+: Both operands must be lists. Useitems + [value]for a new list, orappend(value)for one-item in-place mutation.- A nested list appeared unexpectedly:
append()adds its argument as one object. Useextend()when the contents should become separate elements. - The list variable became
None:append()andextend()mutate the list but returnNone. Do not writeitems = items.append(value). - The wrong number of elements was deleted: A slice stop boundary is excluded. For
del items[:3], indexes0,1, and2are removed. - Elements were skipped in a deletion loop: The list changed positions while it was being iterated. Use a copy or construct a new filtered list.
Key Points
- Lists are mutable, so index assignment,
append(),extend(), anddelcan change the existing list. - Indexes start at zero.
- Use
list_name[index] = valueto replace one element. - Use
+to create a new list from two lists without changing the originals. - Use
append()for one object andextend()for each item from another iterable. - Use
del items[index]for one position anddel items[start:stop]for a range. - Slice stops are excluded.
- Inspect the list after each operation, especially when indexes shift.