Python Sorting Algorithm Example (Bubble Sort)

Bubble sort is a simple sorting algorithm that is often used for learning.

In this example, you will see how bubble sort works in Python with a small step-by-step program. The goal is to understand the algorithm, not to use it as the main way to sort data in real projects.

Use this as a learning example. In normal Python code, sorted() is usually the better choice.

def bubble_sort(numbers):
    items = numbers.copy()
    n = len(items)

    for i in range(n):
        swapped = False
        for j in range(0, n - i - 1):
            if items[j] > items[j + 1]:
                items[j], items[j + 1] = items[j + 1], items[j]
                swapped = True
        if not swapped:
            break

    return items

values = [5, 2, 9, 1, 3]
print(bubble_sort(values))

Output:

[1, 2, 3, 5, 9]

What this example teaches

This example helps you understand several important Python ideas:

  • Bubble sort compares nearby items and swaps them when they are in the wrong order.
  • After each full pass, the largest remaining value moves toward the end.
  • It gives you practice with loops, comparisons, and swapping values.
  • It is useful for learning, but not for most real programs.

If for loops still feel new, see Python for loops explained.

How bubble sort works step by step

Bubble sort works by repeatedly moving through the list and comparing neighboring values.

Here is the basic idea:

  • Start with a list of numbers.
  • Compare item 0 with item 1, then item 1 with item 2, and so on.
  • If the left item is bigger than the right item, swap them.
  • Repeat this process until the list is sorted.
  • After each outer loop pass, one more largest value ends up in the correct position.

Let’s use this list:

[5, 2, 9, 1, 3]

First pass

Compare nearby values from left to right:

  • 5 and 2 → swap → [2, 5, 9, 1, 3]
  • 5 and 9 → no swap
  • 9 and 1 → swap → [2, 5, 1, 9, 3]
  • 9 and 3 → swap → [2, 5, 1, 3, 9]

Now the largest value, 9, has moved to the end.

Second pass

Start again, but stop one item earlier because the last item is already in the right place:

  • 2 and 5 → no swap
  • 5 and 1 → swap → [2, 1, 5, 3, 9]
  • 5 and 3 → swap → [2, 1, 3, 5, 9]

Now 5 is also in the correct position.

Keep repeating

More passes continue until the list becomes:

[1, 2, 3, 5, 9]

Build the Python bubble sort function

Here is the full function again:

def bubble_sort(numbers):
    items = numbers.copy()
    n = len(items)

    for i in range(n):
        swapped = False
        for j in range(0, n - i - 1):
            if items[j] > items[j + 1]:
                items[j], items[j + 1] = items[j + 1], items[j]
                swapped = True
        if not swapped:
            break

    return items

What each part does

1. Create a reusable function

def bubble_sort(numbers):

This puts the sorting logic inside a function so you can use it with different lists.

2. Copy the input list

items = numbers.copy()

This creates a copy so the original list is not changed.

That means this code:

values = [5, 2, 9, 1, 3]
result = bubble_sort(values)

print("original:", values)
print("sorted:", result)

produces:

original: [5, 2, 9, 1, 3]
sorted: [1, 2, 3, 5, 9]

3. Get the list length

n = len(items)

We store the length because we use it several times in the loops.

4. Use an outer loop for repeated passes

for i in range(n):

Each pass moves one more large value into the correct position.

5. Use an inner loop for adjacent comparisons

for j in range(0, n - i - 1):

This loop compares neighboring items:

  • items[j]
  • items[j + 1]

The n - i - 1 part is important. It prevents the loop from going too far and avoids comparing values that are already in the correct place.

6. Swap values when needed

if items[j] > items[j + 1]:
    items[j], items[j + 1] = items[j + 1], items[j]

This checks whether the left value is bigger than the right value.

If it is, the two values are swapped.

The line:

items[j], items[j + 1] = items[j + 1], items[j]

uses tuple assignment, which is a short Python way to swap two values.

Add a simple optimization

This version includes a small improvement:

swapped = False

At the start of each pass, we assume no swaps will happen.

Then, if a swap does happen, we change it:

swapped = True

At the end of the pass:

if not swapped:
    break

If no swap happened, the list is already sorted, so the function stops early.

This makes the example a little better, but bubble sort is still slow compared with Python’s built-in tools like sorted() and list.sort().

Example input and expected output

Here is a complete example:

def bubble_sort(numbers):
    items = numbers.copy()
    n = len(items)

    for i in range(n):
        swapped = False
        for j in range(0, n - i - 1):
            if items[j] > items[j + 1]:
                items[j], items[j + 1] = items[j + 1], items[j]
                swapped = True
        if not swapped:
            break

    return items

values = [5, 2, 9, 1, 3]
sorted_values = bubble_sort(values)

print("Original:", values)
print("Sorted:  ", sorted_values)

Output:

Original: [5, 2, 9, 1, 3]
Sorted:   [1, 2, 3, 5, 9]

Version that sorts in place

If you want to change the original list directly, you can remove .copy():

def bubble_sort_in_place(items):
    n = len(items)

    for i in range(n):
        swapped = False
        for j in range(0, n - i - 1):
            if items[j] > items[j + 1]:
                items[j], items[j + 1] = items[j + 1], items[j]
                swapped = True
        if not swapped:
            break

values = [5, 2, 9, 1, 3]
bubble_sort_in_place(values)
print(values)

Output:

[1, 2, 3, 5, 9]

This version changes the original list.

When not to use bubble sort

Bubble sort is helpful for understanding how sorting works, but it is not a good choice for most real code.

Avoid it when:

  • You are sorting larger lists
  • You want the simplest solution
  • You care about performance

In normal Python code, use:

Common mistakes

Here are some common problems beginners run into when writing bubble sort.

Using the wrong inner loop range

A very common bug is letting j go too far.

Bad example:

def broken_bubble_sort(items):
    n = len(items)
    for i in range(n):
        for j in range(n):
            if items[j] > items[j + 1]:
                items[j], items[j + 1] = items[j + 1], items[j]

This can raise an error because j + 1 becomes invalid near the end of the list.

If you get this problem, see IndexError: list index out of range.

Forgetting to swap values

Sometimes the comparison is correct, but the code never swaps the values.

Make sure you include:

items[j], items[j + 1] = items[j + 1], items[j]

Changing the original list by accident

If you expected the original list to stay the same, use:

items = numbers.copy()

Without that line, the function will change the original list directly.

Using the wrong comparison operator

For ascending order, use:

if items[j] > items[j + 1]:

If you accidentally use <, you will sort in descending order instead.

FAQ

Is bubble sort useful in real Python programs?

Usually no. It is mainly useful for learning how sorting algorithms work.

Should I use sorted() instead of bubble sort?

Yes, in most real code. sorted() is simpler and much faster.

Does this function change the original list?

Not if the function sorts a copy. If it works directly on the input list, then yes.

Why do I get list index out of range?

The inner loop probably goes too far, so j + 1 becomes an invalid index.

See also