Checking if a list is sorted is a common validation task in data processing and algorithm design. You might need to verify if a list is in ascending order (smallest to largest), descending order (largest to smallest), or simply sorted in any valid order.
This guide explores the most readable method using Python's built-in sorted() function, as well as a more memory-efficient algorithmic approach using loops.
Method 1: The "Pythonic" Way (Using sorted)
The simplest way to check if a list is sorted is to sort a copy of it and compare it to the original. If they are identical, the original list was already sorted.
This method is readable and concise but requires creating a copy of the list, which consumes O(n) memory.
numbers = [1, 2, 4, 3, 5]
is_sorted = numbers == sorted(numbers)
print(f"Original: {numbers}")
print(f"Is sorted? {is_sorted}")Output:
Original: [1, 2, 4, 3, 5]
Is sorted? FalseMethod 2: The Efficient Way (Using Iteration)
For very large lists, creating a copy is inefficient. A better algorithmic approach is to iterate through the list and ensure that every element is less than or equal to the next one. This uses O(1) memory and can stop execution as soon as it finds an unsorted element.
Using a for Loop
You must iterate up to len(lst) - 1 to avoid an IndexError when comparing i with i+1.
def is_ascending(lst):
for i in range(len(lst) - 1):
if lst[i] > lst[i + 1]:
return False
return True
data_sorted = [10, 20, 30, 40]
data_unsorted = [10, 30, 20, 40]
print(f"List 1 sorted: {is_ascending(data_sorted)}")
print(f"List 2 sorted: {is_ascending(data_unsorted)}")Output:
List 1 sorted: True
List 2 sorted: FalseUsing all() (Concise Iteration)
You can achieve the same logic in a single line using the all() function with a generator.
data = [1, 2, 3, 4]
is_sorted = all(data[i] <= data[i+1] for i in range(len(data)-1))
print(f"Is sorted: {is_sorted}")Output:
Is sorted: TrueMethod 3: Checking for Descending Order
To check if a list is sorted from largest to smallest, the logic is simply reversed.
Using sorted(reverse=True)
numbers = [5, 4, 3, 2, 1]
is_descending = numbers == sorted(numbers, reverse=True)
print(f"Is descending? {is_descending}")Output:
Is descending? TrueUsing Iteration (Descending)
def is_descending_loop(lst):
for i in range(len(lst) - 1):
if lst[i] < lst[i + 1]:
return False
return True
print(f"Check [5, 3, 1]: {is_descending_loop([5, 3, 1])}")Output:
Check [5, 3, 1]: TrueChecking If Sorted in ANY Order
Sometimes you don't care if it's ascending or descending, just that it is sorted. You can combine the checks.
def is_sorted_any(lst):
return lst == sorted(lst) or lst == sorted(lst, reverse=True)
list_a = [1, 2, 3] # Ascending
list_b = [3, 2, 1] # Descending
list_c = [1, 3, 2] # Unsorted
print(f"List A: {is_sorted_any(list_a)}")
print(f"List B: {is_sorted_any(list_b)}")
print(f"List C: {is_sorted_any(list_c)}")Output:
List A: True
List B: True
List C: FalseConclusion
- For Readability: Use
lst == sorted(lst). It is concise and clear. - For Performance: Use a loop or
all()generator to check elements without copying the list. - For Any Order: Check against both
sorted(lst)andsorted(lst, reverse=True).