How to Check If a List Is Sorted in Ascending Order in Python
Verifying that a list is sorted is a common validation step in algorithms, data processing, and unit testing. While you could write a loop to check every element manually, Python provides concise, functional ways to achieve this efficiently.
This guide explores the two most common methods: comparing against a sorted copy (easiest to read) and iterating through pairs (most performant).
Method 1: Comparing with sorted() (Easiest)
The most readable way to check if a list is sorted is to sort a copy of the list and verify if it matches the original.
The sorted() function returns a new list, leaving the original list unchanged. If the original list is identical
to the new sorted list, then the original was already sorted.
numbers = [1, 2, 3, 5, 8]
unsorted_numbers = [3, 1, 4, 1, 5]
# ✅ Check if list is equal to its sorted version
is_sorted = numbers == sorted(numbers)
is_unsorted = unsorted_numbers == sorted(unsorted_numbers)
print(f"Is 'numbers' sorted? {is_sorted}")
print(f"Is 'unsorted_numbers' sorted? {is_unsorted}")
Output:
Is 'numbers' sorted? True
Is 'unsorted_numbers' sorted? False
How to Check for Descending Order
To check if a list is sorted in descending (reverse) order, use the reverse=True parameter.
desc_list = [9, 8, 5, 2, 1]
# ✅ Check descending
is_descending = desc_list == sorted(desc_list, reverse=True)
print(f"Is descending? {is_descending}")
Output:
Is descending? True
Do not use list.sort() for this check. list.sort() sorts the list in-place and returns None. It modifies your
original data, which is usually not what you want when simply performing a check.
Method 2: Using all() and zip() (Efficient)
While Method 1 is readable, it is computationally expensive (O(N log N)) because it sorts the entire list. A more
efficient approach (O(N)) is to iterate through the list and ensure that every element is less than or equal to the
next element.
We can use zip() to pair elements with their neighbors and all() to verify the condition.
numbers = [1, 2, 4, 3, 5]
# We zip the list with a slice of itself starting from index 1
# This creates pairs: (1,2), (2,4), (4,3), (3,5)
pairs = zip(numbers, numbers[1:])
# ✅ Check if a <= b for every pair
is_sorted = all(a <= b for a, b in pairs)
print(f"Is sorted? {is_sorted}")
Output:
Is sorted? False
Why this is efficient:
The all() function uses lazy evaluation. It stops checking (short-circuits) as soon as it finds the first pair
that is out of order. If the list has 1 million items and the 2nd item is out of order, this method stops immediately,
whereas Method 1 would still sort the entire 1 million items.
Method 3: Using Range Indices
If you prefer avoiding slicing (which creates a shallow copy of the list in memory), you can use indices with a generator expression.
numbers = [1, 2, 3, 4, 5]
# ✅ Iterate through indices from 0 to len-2
# Check if current element <= next element
is_sorted = all(numbers[i] <= numbers[i+1] for i in range(len(numbers) - 1))
print(f"Is sorted? {is_sorted}")
Output:
Is sorted? True
Performance Comparison
| Method | Time Complexity | Space Complexity | Use Case |
|---|---|---|---|
lst == sorted(lst) | O(N log N) | O(N) | Best for small lists or code readability. |
all(... zip(...)) | O(N) | O(N) | Best for large lists; faster due to short-circuiting. |
all(... range(...)) | O(N) | O(1) | Most memory efficient (no slicing copies). |
Conclusion
To check if a list is sorted:
- Use
lst == sorted(lst)for cleaner code on small lists. - Use
all(a <= b for a, b in zip(lst, lst[1:]))for better performance on large lists. - Remember
reverse=Trueif checking for descending order.