Python Program for Bubble Sort (With Examples)

If you have to write a Python program for bubble sort, say for a class or a coding interview, the idea is simple: walk through the list, swap any two neighbors that are out of order, and repeat until a pass makes no swaps.

The swap is one line. It’s the loop bounds that trip you up: one step too far raises an IndexError, and without an early exit you’ll keep looping over a sorted list.

Below, I’ll walk you through three versions, from the plain nested loop to one that sorts records by any field, and why you’d skip it in real code. Outputs are from Python 3.12.5.

The sample prices we’ll sort with bubble sort

You’ll sort the same six order totals from a small online shop in every example:

prices = [24.99, 8.50, 129.00, 3.25, 45.75, 8.50]   # order totals in USD
  • $129.00, the largest, starts in the middle
  • $8.50 shows up twice (two different orders)

The duplicate matters later, when you sort whole orders and want ties to keep their order. To see how bubble sort compares with merge sort and quicksort, read sorting algorithms in Python.

Method 1: Bubble sort in Python with two nested loops

This is the textbook version: the outer loop counts passes, the inner loop compares neighbors and swaps them, as in swapping two numbers in Python. Watch the prices move:

prices = [24.99, 8.50, 129.00, 3.25, 45.75, 8.50]

def bubble_sort(items):
    n = len(items)
    for i in range(n - 1):
        for j in range(n - 1 - i):          # last i items are in place
            if items[j] > items[j + 1]:
                items[j], items[j + 1] = items[j + 1], items[j]
        print(f"Pass {i + 1}: {items}")
    return items

bubble_sort(prices)

Output:

Pass 1: [8.5, 24.99, 3.25, 45.75, 8.5, 129.0]
Pass 2: [8.5, 3.25, 24.99, 8.5, 45.75, 129.0]
Pass 3: [3.25, 8.5, 8.5, 24.99, 45.75, 129.0]
Pass 4: [3.25, 8.5, 8.5, 24.99, 45.75, 129.0]
Pass 5: [3.25, 8.5, 8.5, 24.99, 45.75, 129.0]
Command Prompt output of a Python bubble sort program printing the list of six prices after each of five passes
Each pass moves the largest remaining price right; passes 4 and 5 change nothing.

How does this code work?

In pass 1, j goes from 0 to 4. Whenever items[j] is bigger than the next price, they swap, so $129.00 bubbles to the end.

Each pass fixes one more item at the right, so the inner range shrinks by i. New to computed stops? See for i in range in Python.

So here’s the catch: the list is sorted after pass 3, but passes 4 and 5 still run. Method 2 fixes that.

Method 2: Optimized bubble sort with an early exit (Recommended)

The fix is a swapped flag: if a full pass makes no swaps, the list is sorted, so stop. Here’s the code on the same prices plus an already sorted list:

prices = [24.99, 8.50, 129.00, 3.25, 45.75, 8.50]

def bubble_sort(items):
    n = len(items)
    checks = 0
    for i in range(n - 1):
        swapped = False
        for j in range(n - 1 - i):
            checks += 1
            if items[j] > items[j + 1]:
                items[j], items[j + 1] = items[j + 1], items[j]
                swapped = True
        if not swapped:                     # clean pass: done
            break
    print(f"passes: {i + 1}, comparisons: {checks} -> {items}")
    return items

bubble_sort(prices)
bubble_sort([3.25, 8.50, 8.50, 24.99, 45.75, 129.00])   # already sorted

Output:

passes: 4, comparisons: 14 -> [3.25, 8.5, 8.5, 24.99, 45.75, 129.0]
passes: 1, comparisons: 5 -> [3.25, 8.5, 8.5, 24.99, 45.75, 129.0]
Command Prompt output of an optimized Python bubble sort with a swapped flag, showing passes and comparisons for unsorted and sorted lists
The flag stops after the first clean pass: four passes for the prices, one for the sorted list.

How does this code work?

swapped resets to False at the start of every pass, and any swap sets it to True. Pass 4 on our prices finds nothing to swap, so break stops after 14 comparisons. Method 1 runs 15 for both lists.

That makes the best case linear time. For other hand-written approaches, see sorting a list without the sort() function.

Method 3: Bubble sort in descending order or by a key

Real data is rarely a bare list of numbers. This version takes key and reverse arguments, like built-in sorted().

Here are four of our orders as (id, total) tuples, sorted highest total first:

def bubble_sort(items, key=lambda x: x, reverse=False):
    items = list(items)                     # work on a copy
    n = len(items)
    for i in range(n - 1):
        swapped = False
        for j in range(n - 1 - i):
            a, b = key(items[j]), key(items[j + 1])
            if (a < b) if reverse else (a > b):
                items[j], items[j + 1] = items[j + 1], items[j]
                swapped = True
        if not swapped:
            break
    return items

orders = [("A-1001", 24.99), ("A-1002", 8.50), ("A-1003", 129.00), ("A-1004", 8.50)]
for order in bubble_sort(orders, key=lambda o: o[1], reverse=True):
    print(order)

Output:

('A-1003', 129.0)
('A-1001', 24.99)
('A-1002', 8.5)
('A-1004', 8.5)
Command Prompt output of a Python bubble sort sorting order tuples by total in descending order
Orders sorted by total, highest first, with both $8.50 orders still in their original order.

How does this code work?

key(items[j]) pulls out the value to compare, here the total at index 1. With reverse=True, the test flips to a < b, so bigger values move left.

Look at the two $8.50 orders: A-1002 stays ahead of A-1004. Bubble sort only swaps on a strict difference, so ties never trade places. That makes it stable, like sorting a list of lists in Python with sorted().

Pro Tip: Use >, not >=, in the comparison. With >=, equal items swap on every pass and the sort is no longer stable.

Why is bubble sort so slow on large lists?

Bubble sort compares about n²/2 pairs in the worst case, so it’s O(n²): double the list and it gets roughly four times slower.

Let me show you with random prices (see generating random numbers in Python):

import random, timeit

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

random.seed(2026)
for size in (1_000, 2_000, 4_000):
    data = [round(random.uniform(1, 500), 2) for _ in range(size)]
    slow = timeit.timeit(lambda: bubble_sort(data.copy()), number=1)
    fast = timeit.timeit(lambda: sorted(data), number=1)
    print(f"{size:>5} prices: bubble {slow * 1000:7.1f} ms, sorted() {fast * 1000:5.2f} ms")

Output:

 1000 prices: bubble    28.8 ms, sorted()  0.08 ms
 2000 prices: bubble   127.3 ms, sorted()  0.16 ms
 4000 prices: bubble   537.1 ms, sorted()  0.38 ms
Command Prompt output timing a Python bubble sort against sorted() on 1,000, 2,000 and 4,000 random prices
Doubling the list makes bubble sort roughly four times slower; sorted() stays far faster.

How does this code work?

Each size sorts a fresh copy. Built-in sorted() uses Timsort, which is O(n log n) and written in C. More on that in sorting an array in Python.

Picking the right bubble sort version

VersionBest caseUse it when
Method 1: nested loopsO(n²)You’re learning how passes work
Method 2: early exitO(n)Any assignment or interview answer
Method 3: key and reverseO(n)Sorting records or high to low
sorted() / list.sort()O(n)Real code, always

Next simple algorithm to try: selection sort in Python, which makes fewer swaps but is still O(n²).

Things to Keep in Mind With Bubble Sort in Python

  • The inner loop must stop at n - 1 - i. Going to n makes items[j + 1] raise an IndexError.
  • Methods 1 and 2 sort in place. Pass prices.copy() to keep the original.

Once bubble sort clicks, these related guides are a natural next step:

Frequently asked questions

How do you write a bubble sort program in Python?

Use two loops: the outer counts passes, the inner swaps out-of-order neighbors with a[j], a[j+1] = a[j+1], a[j].

What is the time complexity of bubble sort?

O(n²) on average and worst case, O(n) on a sorted list with an early-exit flag, and O(1) extra space.

How do I sort in descending order with bubble sort?

Flip the comparison from > to <, or add a reverse argument as in Method 3.

Is bubble sort stable?

Yes, if you swap only when one item is strictly greater.

Should I use bubble sort in real Python code?

No. Use sorted() or list.sort(); bubble sort is for learning and interviews.

Where is sorting in Python documented?

See the Sorting Techniques guide in the Python docs.