Python Program for Binary Search with Example and Explanation
mid = (low + high) // 2, adjusting low or high until the target is found or the search space is empty.Examples
How to Think About It
Algorithm
Code
def binary_search(arr, target): low, high = 0, len(arr) - 1 while low <= high: mid = (low + high) // 2 if arr[mid] == target: return mid elif arr[mid] < target: low = mid + 1 else: high = mid - 1 return -1 # Example usage arr = [1, 3, 5, 7, 9] target = 7 result = binary_search(arr, target) print(f"Index of {target} is {result}" if result != -1 else "-1 (not found)")
Dry Run
Let's trace the search for target 7 in the list [1, 3, 5, 7, 9].
Initial pointers
low = 0, high = 4
Calculate mid
mid = (0 + 4) // 2 = 2, arr[mid] = 5
Compare mid value with target
5 < 7, so set low = mid + 1 = 3
Calculate new mid
mid = (3 + 4) // 2 = 3, arr[mid] = 7
Found target
arr[mid] == target, return index 3
| low | high | mid | arr[mid] | action |
|---|---|---|---|---|
| 0 | 4 | 2 | 5 | 5 < 7, move low to 3 |
| 3 | 4 | 3 | 7 | Found target, return 3 |
Why This Works
Step 1: Divide the search space
The code calculates the middle index with mid = (low + high) // 2 to split the list into halves.
Step 2: Compare middle element
It compares the middle element with the target to decide which half to search next.
Step 3: Adjust search range
If the middle element is less than the target, it moves the low pointer up; otherwise, it moves the high pointer down.
Step 4: Repeat until found or empty
This process repeats until the target is found or the search range is empty, returning -1 if not found.
Alternative Approaches
def binary_search_recursive(arr, target, low=0, high=None): if high is None: high = len(arr) - 1 if low > high: return -1 mid = (low + high) // 2 if arr[mid] == target: return mid elif arr[mid] < target: return binary_search_recursive(arr, target, mid + 1, high) else: return binary_search_recursive(arr, target, low, mid - 1) arr = [1, 3, 5, 7, 9] target = 7 result = binary_search_recursive(arr, target) print(f"Index of {target} is {result}" if result != -1 else "-1 (not found)")
import bisect def binary_search_bisect(arr, target): index = bisect.bisect_left(arr, target) if index != len(arr) and arr[index] == target: return index return -1 arr = [1, 3, 5, 7, 9] target = 7 result = binary_search_bisect(arr, target) print(f"Index of {target} is {result}" if result != -1 else "-1 (not found)")
Complexity: O(log n) time, O(1) space
Time Complexity
Binary search cuts the search space in half each step, so it runs in logarithmic time, O(log n).
Space Complexity
The iterative version uses constant extra space, O(1), as it only stores a few variables.
Which Approach is Fastest?
Iterative binary search is fastest in practice due to no recursion overhead; using bisect is concise and optimized but less instructive.
| Approach | Time | Space | Best For |
|---|---|---|---|
| Iterative binary search | O(log n) | O(1) | General use, memory efficient |
| Recursive binary search | O(log n) | O(log n) | Clear code, but uses call stack |
| bisect module | O(log n) | O(1) | Quick, built-in, less code |