Python List Slicing Explained

List slicing lets you get part of a list in Python. It is a very common pattern, and once you understand start, stop, and step, it becomes much easier to read and write Python code.

The basic slice form is:

my_list[start:stop:step]

You can leave out parts of the slice, and Python will use default values. One important rule to remember is that the stop position is not included.

Quick example

numbers = [10, 20, 30, 40, 50]

print(numbers[1:4])   # [20, 30, 40]
print(numbers[:3])    # [10, 20, 30]
print(numbers[::2])   # [10, 30, 50]
print(numbers[::-1])  # [50, 40, 30, 20, 10]

Use list[start:stop:step]. The stop value is not included.

What list slicing means

Slicing gets part of a list.

It uses square brackets with colons:

letters = ["a", "b", "c", "d", "e"]

part = letters[1:4]
print(part)

Output:

['b', 'c', 'd']

Key points:

  • Slicing gets part of a list
  • It uses square brackets with colons
  • Basic form: list[start:stop]
  • The item at stop is not included
  • Slicing returns a new list

If you are still getting comfortable with lists, see the beginner guide to Python lists.

How slice positions work

A slice can have up to three parts:

my_list[start:stop:step]

Here is what each part means:

  • start is where slicing begins
  • stop is where slicing ends before that position
  • step controls how many positions to move each time

If you leave part of the slice out:

  • Missing start means begin at the start of the list
  • Missing stop means go to the end of the list
  • Missing step means use 1

Example:

numbers = [10, 20, 30, 40, 50]

print(numbers[1:4])   # start at index 1, stop before index 4
print(numbers[:3])    # start from the beginning
print(numbers[2:])    # go to the end
print(numbers[::1])   # step of 1

Output:

[20, 30, 40]
[10, 20, 30]
[30, 40, 50]
[10, 20, 30, 40, 50]

Common slicing patterns

These are some of the most useful slice patterns to know:

  • list[:n] gets the first n items
  • list[n:] gets items from position n to the end
  • list[a:b] gets items from a up to b
  • list[::2] gets every second item
  • list[::-1] returns a reversed copy

Example:

numbers = [10, 20, 30, 40, 50, 60]

print(numbers[:3])    # first 3 items
print(numbers[3:])    # from index 3 to the end
print(numbers[1:5])   # items at indexes 1, 2, 3, 4
print(numbers[::2])   # every second item
print(numbers[::-1])  # reversed copy

Output:

[10, 20, 30]
[40, 50, 60]
[20, 30, 40, 50]
[10, 30, 50]
[60, 50, 40, 30, 20, 10]

If you want to make a separate copy of a list, see how to copy a list in Python.

Negative indexes in slices

Negative indexes count from the end of the list.

For example:

  • list[-1] is the last item
  • list[-2] is the second-to-last item

Negative indexes also work in slices.

letters = ["a", "b", "c", "d", "e"]

print(letters[-1])    # last item
print(letters[-3:])   # last 3 items
print(letters[:-1])   # everything except the last item

Output:

e
['c', 'd', 'e']
['a', 'b', 'c', 'd']

Key points:

  • Negative indexes count from the end
  • list[-1] is the last item
  • list[-3:] gets the last three items
  • list[:-1] gets everything except the last item
  • Negative indexes work with both start and stop

Slice step and reverse order

The step value controls how far Python moves each time.

  • A positive step moves left to right
  • A negative step moves right to left
  • list[::-1] is a common way to reverse a list copy
  • If step is negative, start usually needs to be greater than stop
  • step cannot be 0

Example with different step values:

numbers = [10, 20, 30, 40, 50, 60]

print(numbers[::2])     # every second item
print(numbers[1::2])    # every second item starting at index 1
print(numbers[::-1])    # reverse the list
print(numbers[4:1:-1])  # move backward from index 4 to after index 1

Output:

[10, 30, 50]
[20, 40, 60]
[60, 50, 40, 30, 20, 10]
[50, 40, 30]

If you want to reverse a list in other ways, compare this with how to reverse a list in Python.

Step cannot be 0

This causes an error:

numbers = [1, 2, 3]
print(numbers[::0])

Python raises a ValueError because a slice step of 0 does not make sense.

Slicing vs indexing

Slicing and indexing look similar, but they do different things.

Indexing gets one item

numbers = [10, 20, 30, 40]

print(numbers[2])

Output:

30

Slicing gets a new list

numbers = [10, 20, 30, 40]

print(numbers[2:3])

Output:

[30]

Notice the difference:

  • numbers[2] returns one value
  • numbers[2:3] returns a list with one item

Another important difference is error behavior:

  • Out-of-range indexing can raise an error
  • Out-of-range slicing usually does not

Example:

numbers = [10, 20, 30]

print(numbers[5:10])

Output:

[]

But this would raise an error:

numbers = [10, 20, 30]

print(numbers[5])

If you run into that error, see IndexError: list index out of range.

Beginner mistakes to avoid

These are the most common slicing mistakes:

  • Forgetting that stop is not included
  • Using parentheses instead of square brackets
  • Expecting slicing to change the original list
  • Confusing list[::-1] with list.reverse()
  • Using step 0, which causes an error

1. Forgetting that stop is not included

numbers = [10, 20, 30, 40, 50]
print(numbers[1:4])

This returns:

[20, 30, 40]

It does not include 50, because slicing stops before index 4.

2. Using parentheses instead of square brackets

Wrong:

numbers = [10, 20, 30]
# numbers(1:3)

A slice must use square brackets:

print(numbers[1:3])

3. Expecting slicing to modify the original list

A slice creates a new list.

numbers = [10, 20, 30, 40]
part = numbers[:2]

print(part)
print(numbers)

Output:

[10, 20]
[10, 20, 30, 40]

The original list stays the same unless you assign the result back.

4. Confusing list[::-1] with list.reverse()

numbers = [10, 20, 30]

reversed_copy = numbers[::-1]
print(reversed_copy)
print(numbers)

Output:

[30, 20, 10]
[10, 20, 30]

numbers[::-1] creates a reversed copy.

By contrast, numbers.reverse() changes the original list in place.

5. Using a step of 0

This is not allowed:

numbers = [10, 20, 30]
# print(numbers[::0])

Python will raise a ValueError.

Common causes of slicing confusion

If list slicing feels confusing at first, these are usually the reasons:

  • Confusing start and stop positions
  • Assuming the stop index is included
  • Mixing up slicing and indexing
  • Using a negative step without understanding the direction
  • Expecting a slice to modify the original list

A good way to debug slices is to print the list and test small examples:

print(my_list)
print(len(my_list))
print(my_list[1:4])
print(my_list[:3])
print(my_list[-3:])
print(my_list[::-1])

Using len() is especially helpful when you are checking positions in a list. See Python list length with len() if you need a refresher.

FAQ

Does slicing change the original list?

No. A slice creates a new list unless you assign it back.

Is the stop index included in a slice?

No. Python stops before that position.

What does list[::-1] do?

It returns a reversed copy of the list.

Can slicing cause IndexError?

Usually no. Slices that go past the end return the available items.

See also

Practice with small lists first, such as 3 to 5 items. Once slicing feels natural, move on to list indexing, len(), copying, and reversing.