heapq.heapify() does not always guarantee to make an array sorted as we see it when it is printed. All it guarantees is that the first element that is the element at index 0 is the smallest of all. For some inputs, since things fall into place for example [3, 2] we see that after heapify the array to be sorted.
After heapify is called this explanation (from the source code) holds true:
Heaps are arrays for which a[k] <= a[2k+1] and a[k] <= a[2k+2] for
all k, counting elements from 0. For the sake of comparison,
non-existing elements are considered to be infinite. The interesting
property of a heap is that a[0] is always its smallest element.
For the sift down, it just bubbles down a bigger value to its correct place, for example when you delete an element (pop) then the following steps happen:
- Index of the number you want to delete is looked up
- The Last element is put into that index, this might be bigger and can be breaking the binary tree rules.
- Then sift down is called to send this bigger value down to its correct place.
As such siftdown does not promise complete sorting of the array when we print it.
For more implementation details you can lookup heapq.py file within python source.
To always get a sorted representation we can use something like this:
def heapify_demo(nums):
heapq.heapify(nums)
print(nums)
print(heapq.nsmallest(len(nums), nums))
print(heapify_demo([1, 2, 9, 4]))