def insertion_sort_for(arr: list[int]):
for r in range(1,len(arr)):
print(f"\tidx: {[r]}")
for l in range(r,0,-1):
if arr[l]>=arr[l-1]:
print(f"SKIP:\t\t{(l-1,l)},{arr} ")
break
-1],arr[l]=arr[l],arr[l-1]
arr[lprint(f"UPDATED:\t{(l-1,l)},{arr} ")
# print(arr)
return arr
1. Introduction
- I’m currently mostly comfortable using
for
-loops. So I implemented that first then converted it into awhile
-loop.- I used
>=
rather than>
purely for debugging and printing purposes to capture already-sortedSKIP
iterations. - The equivalence is not necessary because the code will reach the end of that particular iteration and go to next decrement (
l--
) (if any), which is the same as skipping theUPDATE
part.
- I used
- My learnings and opinions are at the end.
1.1 CODE-1: for
-loop
1.2 CODE-2: while
-loop
def insertion_sort_while(arr: list[int]):
for r in range(1,len(arr)):
print(f"\tidx: {[r]}")
=r
l# for l in range(r,0,-1):
while l>0 and arr[l]<arr[l-1]:
-1],arr[l]=arr[l],arr[l-1]
arr[lprint(f"UPDATED:\t{(l-1,l)},{arr} ")
-=1
lif l>0 and arr[l]>=arr[l-1]:
print(f"SKIP:\t\t{(l-1,l)},{arr} ")
# print(arr)
return arr
1.3 Helper Function
Because I am too lazy to make the lists manually each time.
def vals_to_list(vals:int):
return [int(val) for val in str(vals)]
2. Five Test Scenarios
I’ll run both versions for 5 test-scenarios:
- Sorted & Unsorted Parts
- Mostly Sorted
- Unsorted (Descending)
- Duplicates
- Already Sorted
2.1 TEST-1: Sorted & Unsorted Parts - for
-loop
= vals_to_list(42713)
arr insertion_sort_for(arr)
idx: [1]
UPDATED: (0, 1),[2, 4, 7, 1, 3]
idx: [2]
SKIP: (1, 2),[2, 4, 7, 1, 3]
idx: [3]
UPDATED: (2, 3),[2, 4, 1, 7, 3]
UPDATED: (1, 2),[2, 1, 4, 7, 3]
UPDATED: (0, 1),[1, 2, 4, 7, 3]
idx: [4]
UPDATED: (3, 4),[1, 2, 4, 3, 7]
UPDATED: (2, 3),[1, 2, 3, 4, 7]
SKIP: (1, 2),[1, 2, 3, 4, 7]
[1, 2, 3, 4, 7]
2.1 TEST-1: Sorted & Unsorted Parts - while
-loop
= vals_to_list(42713)
arr insertion_sort_while(arr)
idx: [1]
UPDATED: (0, 1),[2, 4, 7, 1, 3]
idx: [2]
SKIP: (1, 2),[2, 4, 7, 1, 3]
idx: [3]
UPDATED: (2, 3),[2, 4, 1, 7, 3]
UPDATED: (1, 2),[2, 1, 4, 7, 3]
UPDATED: (0, 1),[1, 2, 4, 7, 3]
idx: [4]
UPDATED: (3, 4),[1, 2, 4, 3, 7]
UPDATED: (2, 3),[1, 2, 3, 4, 7]
SKIP: (1, 2),[1, 2, 3, 4, 7]
[1, 2, 3, 4, 7]
2.2 TEST-2: Mostly Sorted - for
-loop
= vals_to_list(12354)
arr insertion_sort_for(arr)
idx: [1]
SKIP: (0, 1),[1, 2, 3, 5, 4]
idx: [2]
SKIP: (1, 2),[1, 2, 3, 5, 4]
idx: [3]
SKIP: (2, 3),[1, 2, 3, 5, 4]
idx: [4]
UPDATED: (3, 4),[1, 2, 3, 4, 5]
SKIP: (2, 3),[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
2.2 TEST-2: Mostly Sorted - while
-loop
= vals_to_list(12354)
arr insertion_sort_while(arr)
idx: [1]
SKIP: (0, 1),[1, 2, 3, 5, 4]
idx: [2]
SKIP: (1, 2),[1, 2, 3, 5, 4]
idx: [3]
SKIP: (2, 3),[1, 2, 3, 5, 4]
idx: [4]
UPDATED: (3, 4),[1, 2, 3, 4, 5]
SKIP: (2, 3),[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
2.3 TEST-3: Unsorted (Descending) - for
-loop
= vals_to_list(54321)
arr insertion_sort_for(arr)
idx: [1]
UPDATED: (0, 1),[4, 5, 3, 2, 1]
idx: [2]
UPDATED: (1, 2),[4, 3, 5, 2, 1]
UPDATED: (0, 1),[3, 4, 5, 2, 1]
idx: [3]
UPDATED: (2, 3),[3, 4, 2, 5, 1]
UPDATED: (1, 2),[3, 2, 4, 5, 1]
UPDATED: (0, 1),[2, 3, 4, 5, 1]
idx: [4]
UPDATED: (3, 4),[2, 3, 4, 1, 5]
UPDATED: (2, 3),[2, 3, 1, 4, 5]
UPDATED: (1, 2),[2, 1, 3, 4, 5]
UPDATED: (0, 1),[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
2.3 TEST-3: Unsorted (Descending) - while
-loop
= vals_to_list(54321)
arr insertion_sort_while(arr)
idx: [1]
UPDATED: (0, 1),[4, 5, 3, 2, 1]
idx: [2]
UPDATED: (1, 2),[4, 3, 5, 2, 1]
UPDATED: (0, 1),[3, 4, 5, 2, 1]
idx: [3]
UPDATED: (2, 3),[3, 4, 2, 5, 1]
UPDATED: (1, 2),[3, 2, 4, 5, 1]
UPDATED: (0, 1),[2, 3, 4, 5, 1]
idx: [4]
UPDATED: (3, 4),[2, 3, 4, 1, 5]
UPDATED: (2, 3),[2, 3, 1, 4, 5]
UPDATED: (1, 2),[2, 1, 3, 4, 5]
UPDATED: (0, 1),[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
2.4 TEST-4: Duplicates - for
-loop
= vals_to_list(88888)
arr insertion_sort_for(arr)
idx: [1]
SKIP: (0, 1),[8, 8, 8, 8, 8]
idx: [2]
SKIP: (1, 2),[8, 8, 8, 8, 8]
idx: [3]
SKIP: (2, 3),[8, 8, 8, 8, 8]
idx: [4]
SKIP: (3, 4),[8, 8, 8, 8, 8]
[8, 8, 8, 8, 8]
2.4 TEST-4: Duplicates - while
-loop
= vals_to_list(88888)
arr insertion_sort_while(arr)
idx: [1]
SKIP: (0, 1),[8, 8, 8, 8, 8]
idx: [2]
SKIP: (1, 2),[8, 8, 8, 8, 8]
idx: [3]
SKIP: (2, 3),[8, 8, 8, 8, 8]
idx: [4]
SKIP: (3, 4),[8, 8, 8, 8, 8]
[8, 8, 8, 8, 8]
2.5 TEST-5: Already Sorted - for
-loop
= vals_to_list(12345)
arr insertion_sort_for(arr)
idx: [1]
SKIP: (0, 1),[1, 2, 3, 4, 5]
idx: [2]
SKIP: (1, 2),[1, 2, 3, 4, 5]
idx: [3]
SKIP: (2, 3),[1, 2, 3, 4, 5]
idx: [4]
SKIP: (3, 4),[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
2.5 TEST-5: Already Sorted - while
-loop
= vals_to_list(12345)
arr insertion_sort_while(arr)
idx: [1]
SKIP: (0, 1),[1, 2, 3, 4, 5]
idx: [2]
SKIP: (1, 2),[1, 2, 3, 4, 5]
idx: [3]
SKIP: (2, 3),[1, 2, 3, 4, 5]
idx: [4]
SKIP: (3, 4),[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
3. Ending Comments
Results are the same which is a good sign.
This algorithm took me a while to get my head around:
- Easier: I have rarely used
while
-loops in my career, and thus lacking in confidence using them, but thewhile
implementation seems to be:- easier to read
- easier to debug
- easier to write (perhaps, I’ll need to practice a bit more)
- Looping both ways: Conceptually new to me is:
- An outer loop or
r
to count forward and an - Inner-loop or
l
and to backward . - I’ve always counted forwards when using nested-loops.
- An outer loop or
- Other Learnings: This algorithm has helped me to:
- Better understand and
- Implement the conversion between
for
towhile
loops.