Python online course

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.

ExpressionPosition affectedExplanation
items[0]First itemIndexes begin at zero.
items[1]Second itemThe position one comes after index zero.
items[:3]Indexes 0, 1, and 2The stop index 3 is excluded.
items[1:3]Indexes 1 and 2The start is included and the stop is excluded.
items[-1]Last itemNegative 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 callInputList resultKey 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

OperationSyntax patternChanges original list?Result
Replace one itemitems[index] = valueYesOne element is replaced.
Combine listscombined = items + extrasNoA new combined list is created.
Add one itemitems.append(value)YesOne object is added at the end.
Add many itemsitems.extend(values)YesEach item from the iterable is added.
Delete one itemdel items[index]YesOne position is removed.
Delete a rangedel items[start:stop]YesA contiguous slice is removed.
Delete a range with assignmentitems[start:stop] = []YesThe 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

  • IndexError when replacing or deleting: The index does not exist in the current list. Remember that the first index is 0, and inspect len(items) before using a position.
  • TypeError with +: Both operands must be lists. Use items + [value] for a new list, or append(value) for one-item in-place mutation.
  • A nested list appeared unexpectedly: append() adds its argument as one object. Use extend() when the contents should become separate elements.
  • The list variable became None: append() and extend() mutate the list but return None. Do not write items = items.append(value).
  • The wrong number of elements was deleted: A slice stop boundary is excluded. For del items[:3], indexes 0, 1, and 2 are 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(), and del can change the existing list.
  • Indexes start at zero.
  • Use list_name[index] = value to replace one element.
  • Use + to create a new list from two lists without changing the originals.
  • Use append() for one object and extend() for each item from another iterable.
  • Use del items[index] for one position and del items[start:stop] for a range.
  • Slice stops are excluded.
  • Inspect the list after each operation, especially when indexes shift.