In [10]:
from functools import partial
def ins_sort(xs, rev=False):
xs = xs[:]
comp = (lambda k, t: t < k) if rev else (lambda k, t: t > k)
for j in range(1, len(xs)):
i = j - 1
k = xs[j]
comp_foo = partial(comp, k)
while i >= 0 and comp_foo(xs[i]):
xs[i+1] = xs[i]
i -= 1
xs[i+1] = k
return xs
In [11]:
import numpy as np
from functools import partial
from operator import mul
a = list(map(partial(mul, 10), np.random.rand(10000)))
%timeit ins_sort(a)
%timeit ins_sort(a, True)
First of all we need to implement merge function. For this function I implement next algorithm.
In [5]:
def merge(xs, ys, cf=lambda a, b: b if a > b else a):
zs = []
xl, yl = len(xs), len(ys)
zl = xl + yl
xi = yi = 0
for _ in range(zl):
if xi == xl:
while yi < yl:
zs.append(ys[yi])
yi += 1
break
elif yi == yl:
while xi < xl:
zs.append(xs[xi])
xi += 1
break
zs.append(cf(xs[xi], ys[yi]))
if xs[xi] < ys[yi]:
xi += 1
else:
yi += 1
return zs
Now lets write classic recursive merge sort.
In [6]:
def classic_merge_sort(xs):
if len(xs) < 2:
return xs
q = len(xs) // 2
ys = classic_merge_sort(xs[:q])
zs = classic_merge_sort(xs[q:])
return merge(ys, zs)
In [9]:
import numpy as np
from functools import partial
from operator import mul
a = list(map(partial(mul, 10), np.random.rand(10000)))
%timeit classic_merge_sort(a)
So, merge sort is notably faster than insertion sort, but in python recursion is not best solution.