Python’s built-in sorted()
function enables programmers to sort a list efficiently and easily. On the other hand, the list.sort()
method provides an in-place sorting mechanism. Additionally, Python allows for custom sorting using the key
parameter in these functions, enabling more advanced sorting scenarios.
In this article, I’ll show you how to find an element in a Python data structure (e.g., list, set, dict, tuple) that is already sorted.
Binary search is a powerful technique to search through sorted lists at lightning speed. Python’s standard library provides the bisect
module, which offers utilities that facilitate binary search operations on sorted lists, making it an attractive option for working with sorted data.
Finding Elements in Sorted Lists
Searching for elements in a sorted list can be much more efficient compared to an unsorted list. In this section, we’ll discuss three methods for finding elements in sorted lists: Binary Search, Bisect_left
, and Bisect_right
. 🌟
Binary Search
🔍 Binary search is a classic algorithm to search for an element in a sorted list. It works by repeatedly dividing the list in half and checking the middle element.
👉 If the middle element matches the target, we’re done.
👉 If the middle element is greater than the target, the target must lie in the left half.
👉 If the middle element is less than the target, the target must lie in the right half.
This process continues until the target is found or the list is exhausted.
Here is a simple implementation:
def binary_search(lst, target): left, right = 0, len(lst) - 1 while left <= right: mid = left + (right - left) // 2 if lst[mid] == target: return mid elif lst[mid] < target: left = mid + 1 else: right = mid - 1 return -1
🔍 More efficient than a linear search, the binary search algorithm operates in O(log n) time complexity.
Bisect_left
The bisect_left()
function from Python’s built-in bisect
module is an alternative to the binary search algorithm. It finds the index of where the target element should be inserted to maintain the sorted order. If the target is already present in the input list, it returns the index of the leftmost occurrence of the target.
Here’s an example of using bisect_left
:
from bisect import bisect_left lst = [1, 3, 4, 4, 6, 8] target = 4 index = bisect_left(lst, target) # Check if the index contains the target in the list if index != len(lst) and lst[index] == target: print(f"Element found at index {index}") else: print("Element not found.")
💡 This function can be handy for maintaining sorted lists, updating them as new elements are inserted.
Bisect_right
Similar to bisect_left()
, the bisect_right()
function from the bisect
module returns the index where the target element should be inserted while preserving the order of the input sorted list. However, it returns the index of the rightmost occurrence of the target in the case that the target already exists in the list.
Here’s an example with bisect_right
:
from bisect import bisect_right lst = [1, 3, 4, 4, 6, 8] target = 4 index = bisect_right(lst, target) # Check if the index-1 contains the target in the list if index > 0 and lst[index - 1] == target: print(f"Element found at index {index - 1}") else: print("Element not found.")
📌 Both bisect_left
and bisect_right
offer a clear and concise way to find elements in sorted lists, while maintaining the order efficiently.
By understanding and applying these three methods, searching for elements in sorted lists becomes a breeze. Happy coding! 🎉
Built-in Python Functions and Methods
Sorted Function
The sorted()
function is a built-in Python function that takes an iterable and returns a new sorted list. It’s not limited to lists, accepting various iterable data types. This function is particularly useful when you need a sorted version of the original iterable without modifying it. 🧐
Here’s an example:
numbers = [4, 1, 3, 2] sorted_numbers = sorted(numbers) print(sorted_numbers) # Output: [1, 2, 3, 4]
You can also customize the sorting using arguments like key
and reverse
. For example, using lambda
function with sorted()
:
students = [('Alice', 18), ('Bob', 20), ('Charlie', 17)] sorted_students = sorted(students, key=lambda x: x[1], reverse=True) print(sorted_students) # Output: [('Bob', 20), ('Alice', 18), ('Charlie', 17)]
Sort Method
Python lists have a built-in sort()
method that modifies the list in-place. It returns None
, emphasizing that the original list is changed, and no new list is created. 🔄
Example of using sort()
method:
numbers = [4, 1, 3, 2] numbers.sort() print(numbers) # Output: [1, 2, 3, 4]
Similar to sorted()
function, the sort()
method also accepts key
and reverse
arguments:
students = [('Alice', 18), ('Bob', 20), ('Charlie', 17)] students.sort(key=lambda x: x[1], reverse=True) print(students) # Output: [('Bob', 20), ('Alice', 18), ('Charlie', 17)]
Other List Methods
Several other list methods are useful in handling sorted lists. For example, index()
, count()
, len()
, and pop()
can provide valuable insights or modify the list when needed. 📝
index()
: Returns the first index of a given value.count()
: Returns the number of occurrences of a given value.len()
: Returns the length of the list.pop()
: Removes an item at a specified index and returns it.
Here’s an example:
numbers = [1, 2, 3, 4, 4, 4, 5] index_4 = numbers.index(4) num_4 = numbers.count(4) length_numbers = len(numbers) last_item = numbers.pop() print(index_4) # Output: 3 print(num_4) # Output: 3 print(length_numbers) # Output: 7 print(last_item) # Output: 5
You can download my Python list methods cheat sheet by clicking on the image here:
Sorting Techniques
Sorting Lists
In Python, you can easily sort a list in ascending order using the sorted()
function or the list.sort()
method. The sorted()
function returns a new sorted list, while list.sort()
modifies the original list in-place.
numbers = [5, 2, 3, 1, 4] sorted_numbers = sorted(numbers) # returns [1, 2, 3, 4, 5] numbers.sort() # modifies numbers to [1, 2, 3, 4, 5]
For descending order, add the reverse=True
parameter:
descending_numbers = sorted(numbers, reverse=True) # returns [5, 4, 3, 2, 1]
Sorting Tuples
Tuples are immutable, so you can only use the sorted()
function to get a sorted list of its elements. You can then convert the list back to a tuple if needed.
tuple_example = (5, 2, 3, 1, 4) sorted_tuple = tuple(sorted(tuple_example)) # returns (1, 2, 3, 4, 5)
Sorting Strings
Strings can also be sorted using the sorted()
function, which returns a list of characters in alphabetical order. To convert the result back to a string, use ''.join()
.
string_example = "hello" sorted_string = ''.join(sorted(string_example)) # returns "ehllo"
Sorting Sets
Sets are unordered, but you can still sort their elements using the sorted()
function, which then returns a sorted list.
set_example = {5, 2, 3, 1, 4} sorted_set = sorted(set_example) # returns [1, 2, 3, 4, 5]
We have actually created a video on sorting sets here:
👉 Recommended: How To Sort A Set Of Values?
Sorting Dictionaries
Dictionaries can be sorted by keys or values. Use the sorted()
function along with a lambda function as a key
parameter to specify the sorting criteria.
dict_example = {"a": 3, "b": 1, "c": 2} sorted_by_key = dict(sorted(dict_example.items())) # returns {"a": 3, "b": 1, "c": 2} sorted_by_value = dict(sorted(dict_example.items(), key=lambda item: item[1])) # returns {"b": 1, "c": 2, "a": 3}
Remember to keep the sorting techniques simple and appropriate for the data types you’re working with! 🐍💡
Custom Sorting
Using Key Argument
The key
argument allows you to provide a custom sorting criterion for your lists. It takes a function as a value, which is applied to each element of the list before performing the actual sort. 🐍
For instance, the following code sorts a list of numbers by their absolute values:
numbers = [-5, 3, -2, 1, 4] sorted_numbers = sorted(numbers, key=abs)
Here, the abs()
function gets the absolute value of each number, and the list is sorted accordingly. You can also use lambda functions for more complex sorting criteria:
data = [("apple", 3), ("banana", 1), ("orange", 2)] sorted_data = sorted(data, key=lambda x: x[1])
In this example, the key
argument specifies that the second element of each tuple should be used as the sorting criterion.
Using Reverse Parameter
The reverse
parameter is a simple boolean flag that allows you to change the sort order from ascending (default) to descending. 🔁 To use it, just set it to True
:
numbers = [1, 2, 3, 4, 5] sorted_numbers = sorted(numbers, reverse=True)
This will yield a sorted list [5, 4, 3, 2, 1]
, which is sorted in descending order.
Using Cmp Parameter
⚠️ The cmp
parameter was used in Python 2 for providing a custom comparison function to the sorted
and list.sort()
functions. However, it’s been removed in Python 3, but you can achieve the same functionality using the key
parameter or functools module.
Here’s how to use the key
parameter to implement custom comparison logic:
def custom_compare(x): # Your custom comparison logic here return x data = [1, 2, 3, 4, 5] sorted_data = sorted(data, key=custom_compare)
Replace the comment with your own logic for sorting your data.
For more advanced use cases, you can leverage the functools
module and its cmp_to_key
function:
import functools def custom_compare(x, y): # Your custom comparison logic here return x - y data = [1, 2, 3, 4, 5] sorted_data = sorted(data, key=functools.cmp_to_key(custom_compare))
Again, replace the comment with your own comparison logic for better control over the sorting process. 🛠️ Remember, though, that using the key
argument is usually more efficient and easier to understand.
Advanced Sorting Concepts
Sorting in NumPy
NumPy, a popular library in Python, offers powerful tools for sorting arrays efficiently. The sort
function in NumPy can be applied to one-dimensional arrays and allows sorting in both ascending and descending order. To sort a NumPy array, you can simply use the following syntax:
import numpy as np arr = np.array([9, 3, 5, 1]) sorted_arr = np.sort(arr)
In cases where you need to sort a two-dimensional array along a specific axis (e.g., left to right or side to side), you can use the axis
parameter:
arr_2d = np.array([[3, 2, 1], [6, 5, 4]]) sorted_arr_2d = np.sort(arr_2d, axis=1)
Moreover, NumPy also provides the argsort
function, which returns the indices of the sorted elements instead of the actual values.
Sorting Complex Numbers
Python has built-in support for complex numbers, and sorting them can be a bit tricky. Since complex numbers have both real and imaginary parts, comparisons are not directly possible using traditional sorting methods.
To sort a list of complex numbers, you can create a comparison function that returns a specific value based on the properties of the complex numbers. For instance, you can sort based on the real part, the imaginary part, or the magnitude:
complex_list = [1 + 2j, 2 + 1j, 3 + 4j] sorted_by_real = sorted(complex_list, key=lambda x: x.real) sorted_by_imag = sorted(complex_list, key=lambda x: x.imag) sorted_by_magnitude = sorted(complex_list, key=lambda x: abs(x))
Keep in mind that the above examples use the sorted
function, which creates a new sorted list without altering the original one. If you want to sort the list in-place, you may use the .sort()
method instead, with the same key
parameter.
By using NumPy and custom sorting functions, you can confidently sort a wide range of iterables in Python, including complex numbers and even more advanced data types. Just remember the importance of choosing the right sorting strategy and the specific properties to use as comparison metrics. 😊
Operations on Sorted Lists
In this section, we will discuss various operations on sorted lists in Python. These operations include inserting elements, removing elements, and performing copy and in-place operations.
Inserting Elements
When working with sorted lists, you may want to insert elements while maintaining the sorted order. In Python, you can use the bisect.insort()
function from the bisect
module to accomplish this.
The syntax for using insort()
is:
import bisect bisect.insort(array, element)
where array
is the sorted list, and element
is the item you wish to insert in the correct position to maintain the sorted order. For example:
import bisect numbers = [1, 3, 4, 6, 8] bisect.insort(numbers, 5) print(numbers)
This code would output [1, 3, 4, 5, 6, 8]
, as the new element 5
is inserted in the appropriate position to maintain the ascending order. 😊
Removing Elements
To remove an element from a sorted list, you can use the remove()
method. The syntax for using remove()
is:
array.remove(element)
where array
is the sorted list, and element
is the item you wish to remove from the list. Please note that this method will remove the first occurrence of the specified item. For example:
numbers = [1, 3, 4, 6, 8] numbers.remove(3) print(numbers)
This code would output [1, 4, 6, 8]
, as the element 3
is removed from the list.
Copy and In-place Operations
When working with sorted lists, you might want to create a copy of a list or perform in-place operations. To create a copy of the list, you can use the copy()
method:
new_list = array.copy()
For in-place operations, you have a few options. To sort a list in-place, you can use the sort()
method:
array.sort()
This method sorts the elements in the list in ascending order by default. However, you can also specify optional parameters such as key
for a custom sorting function and reverse
to sort the list in descending order. For example:
array.sort(reverse=True)
Another in-place operation is append()
, which adds an element to the end of the list:
array.append(element)
Please note that when using append()
, the new element may not be inserted in the correct position to maintain the sorted order. This operation is best used when adding elements to the list before sorting it. In such cases, don’t forget to call the sort()
method afterwards to maintain the sorted order. 😉
Frequently Asked Questions
How to perform binary search in Python?
Binary search is an efficient algorithm for finding an element in a sorted list. Python’s bisect
library provides an easy way to perform binary search. You can use bisect_left
or bisect_right
from the bisect
module to find the position where an element can be inserted while maintaining the sorted order. 😊
from bisect import bisect_left sorted_list = [1, 3, 4, 4, 6, 8] x = 4 # Find the position using binary search index = bisect_left(sorted_list, x) print(f"Element {x} should be inserted at: {index}")
What is the purpose of bisect in Python?
The purpose of bisect
module in Python is to provide functions for searching and inserting elements into sorted lists while maintaining their sorted order. It is useful when working with large datasets where sorting elements is computationally expensive or maintaining a sorted list at all times is crucial. 👍
How to search for an element in a sorted array using Python?
To search for an element in a sorted array using Python, you can use binary search algorithm which can be implemented with the help of bisect_left
function from the bisect
module. When searching for an element, the bisect_left
function returns the index of the element if it is present in the list or the index where the element should be inserted while maintaining the sorted order. 😃
What is the time complexity of searching in a sorted list in Python?
Searching for an element in a sorted list using the binary search algorithm has time complexity of O(log n), where n is the number of elements in the list. This time complexity makes binary search an efficient method for searching elements in large sorted lists. ⏱️
How to find the index of an element in a sorted list in Python?
You can find the index of an element in a sorted list in Python by using the bisect_left
function from the bisect
module. The bisect_left
function will return the index of the element if it is present in the list. Otherwise, it will return the index where the element should be inserted while maintaining the sorted order. ✨
from bisect import bisect_left sorted_list = [1, 3, 4, 4, 6, 8] x = 4 # Find the index using binary search index = bisect_left(sorted_list, x) print(f"Element {x} found at index: {index}" if sorted_list[index] == x else f"Element {x} not found")
What is the difference between bisect_left and bisect_right in Python?
bisect_left
and bisect_right
are two functions from the bisect
module that work with sorted lists. The difference between the two lies in how they handle duplicate elements:
bisect_left
: Returns the leftmost index where an element can be inserted into the sorted list while maintaining the sorted order. If the element already exists in the list, it returns the index of the first occurrence.bisect_right
: Returns the rightmost index where the element can be inserted into the sorted list while maintaining the sorted order. If the element already exists in the list, it returns the index just after the last occurrence. 🌟

While working as a researcher in distributed systems, Dr. Christian Mayer found his love for teaching computer science students.
To help students reach higher levels of Python success, he founded the programming education website Finxter.com that has taught exponential skills to millions of coders worldwide. He’s the author of the best-selling programming books Python One-Liners (NoStarch 2020), The Art of Clean Code (NoStarch 2022), and The Book of Dash (NoStarch 2022). Chris also coauthored the Coffee Break Python series of self-published books. He’s a computer science enthusiast, freelancer, and owner of one of the top 10 largest Python blogs worldwide.
His passions are writing, reading, and coding. But his greatest passion is to serve aspiring coders through Finxter and help them to boost their skills. You can join his free email academy here.