Insertion Sort in python using Key - python

def insertion_sort2(A):
for i in range(1,len(A)):
key = A[i]
j = i-1
for j in range(i-1,0,-1):
if A[j] > key :
A[j+1] = A[j]
else:
A[j+1] = key
break
for i in range(1, len(arr)):
key = arr[i]
j = i-1
while j >=0 and key < arr[j] :
arr[j+1] = arr[j]
j -= 1
arr[j+1] = key
Hello I have tried both methods to do simple Insertion Sort in c++ it works but in python it is not working,but both of them are giving answers like
1st one:
[56, 77, 77, 77, 77, 77, 77, 99]
2nd one:
does not sort even
Note:The second one starts after break and I have not run them both together,I commented out one and then run the other one

First of all you don't go upto the 0th element in the array in the inner loop. In python's range function, the range is counted uptil one before the second term. On putting range(i-1,-1,-1) the range becomes i-1 to 0.
Secondly, you are not swapping the two consecutive elements , just assigning (j)th element a value of (j+1)th element. But what about assigning jth value to (j-1)th element.
Third, there's no meaning of doing A[j+1] = key as it already is key.
def insertion_sort2(A):
for i in range(1,len(A)):
key = A[i]
j = i-1
for j in range(i-1,-1,-1):
if A[j] > key :
A[j+1], A[j] = A[j], A[j+1]
else:
break

Related

Implementation of Insertion Sort Algorithm in python

I was trying to implement the insertion sort algorithm in python and was able to code it as below, I am not getting the whole array sorted and was wondering if this implementation has the proper thought process behind it, if not I would greatly appreciate if someone can help me in understanding it as the function is considering the sorted part of the array when inserting an element from the unsorted part. Also, in your review kindly consider if the implementation is correct and if so what can make my solution output correct.
def insertion_sort(array):
for i in range(1, len(array)):
for j in reversed(range(1, i)):
if array[j-1] > array[j]:
temp = array[j-1]
array[j-1] = array[j]
array[j] = temp
return array
to_sort = [4, 3, 1, 5, 6, 2]
print(insertion_sort(to_sort))
This is the output I got:
[1, 3, 4, 5, 6, 2]
tl;dr:
Insertion Sort algorithm not giving perfect output. Is implementation correct and what can be done to fix the output.
The goal of your function would be to shift array[i] into the sorted partition, but it actually does that for array[i-1], because the inner loop starts with j equal to i-1.
So the easy fix is to change:
for j in reversed(range(1, i)):
to:
for j in reversed(range(1, i + 1)):
Improvements
More Pythonic would be to use the capability of range to produce a descending range:
for j in range(i, 0, -1):
When the if condition is not true, it is useless to continue the inner loop, as then it is guaranteed that the if condition will never be true in the rest of the inner loop's iterations. So add a break:
if array[j-1] <= array[j]:
break
temp = array[j-1]
array[j-1] = array[j]
array[j] = temp
As these swaps will always move the same value to the left, i.e. array[j] will always be the value that originally was at array[i], it is less costly to first find the index where array[i] should be moved to, and then perform a single rotation to get it there.
def insertion_sort(array):
for i in range(1, len(array)):
temp = array[i]
for k in range(i - 1, -1, -1):
if array[k] <= temp:
break
else:
k = -1
# rotate
array[k+2:i+1] = array[k+1:i]
array[k+1] = temp
return array
I used k here, so not to confuse it with the meaning of j in the original code: k is j - 1.
This search for k (or j) can be done with a call to next:
def insertion_sort(array):
for i in range(1, len(array)):
temp = array[i]
j = 1 + next((k for k in range(i - 1, -1, -1) if array[k] <= temp), -1)
array[j+1:i+1] = array[j:i]
array[j] = temp
return array
You are never touching the last element of the array, I suggest changing len(array) with len(array)+1, i.e.,
def insertion_sort(array):
for i in range(1, len(array)+1):
for j in reversed(range(1, i)):
if array[j-1] > array[j]:
temp = array[j-1]
array[j-1] = array[j]
array[j] = temp
return array
This is because i has maximum value len(array)-1 and j has as maximum value i-1, which is len(array)-2.
However, the last element in the array has index len(array)-1.

Python Iterating and Comparing Multiple Lists

I have two lists of equal length: a and b. List b contains several of the same floating point numbers as list a at the same indices, but the other indices are replaced with zeros. These lists also contain several thousand values each.
I would like to iterate through list b until it gets to a non-zero value then iterate through list a from the same index until a greater value is reached. I want to then append that greater value to an empty list and then continue to iterate through list b until the next non-zero value and repeat.
c=[]
i = 0
j = 0
while i < len(a):
if b[i] == 0:
i = i + 1
if b[i] > 0:
j = i
if a[j] < b[i]:
j = j + 1
if a[j] == b[i]:
j = j + 1
if a[j] > b[i]:
c.append(a[j])
i = i + 1
I have tried multiple ways to do this with for and while loops and either end up just appending the whole of list a into the empty list or I create an infinite while loop, so any help or advice on how to get started would be greatly appreciated!
Incorporating #MichaelButscher's answer into this and adding another list d that contains dates that correspond to the values in lists a and b, I then appended the dates for the values that met the condition if a[j] > b[i]: into a new list e.
d=['05/01/2000','06/01/2000','07/01/2000','10/01/2000','11/01/2000','12/01/2000','23/10/2000','24/10/2000','25/10/2000','13/12/2000','14/12/2000','15/12/2000','20/02/2001','21/02/2001','21/09/2001','19/06/2002','20/06/2002']
a=[1.86,1.85,1.89,1.82,1.82,1.83,1.846,1.898,1.869,1.923,1.926,1.9677,1.959,2.02,2.802,2.7312,2.8035]
b=[0,0,1.89,0,0,0,0,0,0,0,0,1.9677,0,0,2.802,0,0]
c=[]
e=[]
i = 0
j = 0
# Run until break
while True:
while i < len(a):
if b[i] != 0:
break # break inner while
i += 1
else:
break # break outer while
# At this point: i < len(a) and b[i] != 0
j = i
while j < len(a):
if a[j] > b[i]:
# At this point: i < len(a) and b[i] != 0 and j < len(a) and a[j] > b[i]
c.append(a[j])
e.append(d[j])
break
j += 1
# At this point either appropriate j was found or j == len(a)
# Anyway, next i to check
i += 1
lists c and e were then printed in columns:
24/10/2000 1.898
24/10/2000 1.898
21/02/2001 2.02
10/09/2001 2.606
20/06/2002 2.8035
24/09/2002 3.8132
22/09/2015 4.0667
04/09/2015 3.853
01/09/2015 3.7031
10/05/2004 3.148
Some of the data is repeated and isn't in ascending date order even though the dates in list d were.
This can be done by nesting while loops. Outer while just runs forever (until break) inner while loops check for desired state.
Untested but should work:
c=[]
i = 0
j = 0
# Run until break
while True:
while i < len(a):
if b[i] != 0:
break # break inner while
i += 1
else:
break # break outer while
# At this point: i < len(a) and b[i] != 0
j = i
while j < len(a):
if a[j] > b[i]:
# At this point: i < len(a) and b[i] != 0 and j < len(a) and a[j] > b[i]
c.append(a[j])
break
j += 1
# At this point either appropriate j was found or j == len(a)
# Anyway, next i to check
i += 1

Python code for Insertion sort taking input as a string value

This Python code gives sorted elements according to string elements.
How we convert list elements, which are in string format in integer type?
This is my code:
def insertionSort(arr, n):
for i in range(1, n):
key = arr[i]
j = i - 1
while j >= 0 and arr[j] > key:
arr[j+1] = arr[j]
j = j - 1
arr[j+1] = key
print '\nSorted elements: ',
return (' ').join(arr)
arr = (raw_input("enter elements: ")).split(',')
print insertionSort(arr, len(arr))
you have to convert your elements using a element to key function so you can use comparison not of the element itself but of a transformed data suiting your needs.
I would do this as a generic solution:
def insertionSort(arr, n, keyfunc=lambda x:x):
for i in range(1, n):
key = arr[i]
j = i - 1
while j >= 0 and keyfunc(arr[j]) > keyfunc(key):
arr[j+1] = arr[j]
j = j - 1
arr[j+1] = key
return ' '.join(arr)
so by default, the key is just the element itself, but if you call your function like this:
insertionSort(arr, len(arr), keyfunc=int)
the key function is now "conversion to integer", and sorting works as expected on a list of integers as strings.
(note that the built-in sort method works that way, by allowing to provide a key function).
of course you can drop the whole keyfunc idea and just hardcode int here:
while j >= 0 and int(arr[j]) > int(key):

Sorting in python does not work

i'm a beginning python programmer and i'm trying to write a code that sorts data in an array in increasing order as below:
A = [2,3,6,8,4,5,7,123,543,65435,31,43]
for i in range(len(A)-1):
if A[i] > A[i+1]:
A[i] , A[i+1] = A[i+1] , A[i]
print (A)
However the result returns this:
[2, 3, 6, 4, 5, 7, 8, 123, 543, 31, 43, 65435]
May I know what I'm doing wrong? Any help would be much appreciated. Thanks!
You are only performing a single stage of bubble-sort; to get the list completely sorted, you would have to float the numbers up n - 1 times, not only one.
Try this:
for i in range(len(A)-1):
for i in range(len(A)-1):
if A[i] > A[i+1]:
A[i] , A[i+1] = A[i+1] , A[i]
You are trying to do Bubble Sort. Actually the part of your code works, In your result the greatest element is at the end of the sorted array. Now you have to do the same for all remaining elements in a nested for loop. That's why Bubble Sort has the complexity of O(n^2)
A = [2,3,6,8,4,5,7,123,543,65435,31,43]
for i in range(0,len(A)):
for j in range(i+1):
if A[i] > A[j]:
A[i] , A[j] = A[j] , A[i]
print A
Sorting needs comparing an element with rest of the elements in that array

Is that Insertionsort?

I really need your help, I am learning sorting-algorithms and i tried to make an Insertionsort-Algorithm. So could you please tell me whether this is an Insertionsort-Algorithm or not?
def insertsort(l):
for k in range(len(l)):
for i in range(1,len(l)):
if l[i]<l[i-1]:
while l[i]<l[i-1]:
l.insert(i-1,l.pop(i))
return l
yes, it is insertion sort. The pseudocode is as follows:
1. for j = 2 to n
2. key ← A [j]
3. // Insert A[j] into the sorted sequence A[1..j-1]
4. j ← i – 1
5. while i > 0 and A[i] > key
6. A[i+1] ← A[i]
7. i ← i – 1
8. A[j+1] ← key
I do not think so. You used two nested for loops and a while. In the pseudocode provided by #dreadedHarvester and the implementation provided in RosettaCode just one for loop and one while are used.
def insertion_sort(l):
for i in xrange(1, len(l)):
j = i-1
key = l[i]
while (l[j] > key) and (j >= 0):
l[j+1] = l[j]
j -= 1
l[j+1] = key

Categories