I’m trying to write a merge-sort function that takes a list and a comparison function, in Python:
def sort(unsorted, comp_func=lambda x, y: x < y):
length = len(unsorted)
if length <= 1: return unsorted
halflen = length / 2
lsorted= sort(unsorted[:halflen])
rsorted = sort(unsorted[halflen:])
combined = []
while True:
if len(lsorted) > 0:
if len(rsorted) > 0 and comp_func(rsorted[0], lsorted[0]):
combined.append(rsorted[0])
rsorted = rsorted[1:]
else:
combined.append(lsorted[0])
lsorted = lsorted[1:]
elif len(rsorted) > 0:
combined.append(rsorted[0])
rsorted = rsorted[1:]
else:
break
return combined
It works fine with lists of int (with the default comp_func), as well as lists of tuples that have 2 int when the comparison function compares the first element of such a tuple.
comp_func = lambda x, y: x[0] < y[0]
But when I write the comparison function to compare by the second element of the tuple, the list returned is still the unsorted version.
comp_func = lambda x, y: x[1] < y[1]
However, if I change the ‘<‘ operator to ‘>’ so that the list is to be sorted decrementally, it works:
comp_func = lambda x, y: x[1] > y[1]
Don’t know why ‘<‘ fails on the second element of the tuples…
Having searched for a possible explanation, I found this: Does python think 10 is less than 9. However, that is not the case; the list being sorted contain tuples of int, not string.
You don’t actually show a transcript of how you changed the operator, so this is just a guess, but notice that these two lines
don’t pass comp_func. So if you did something like this:
you would get inconsistent results because half the time it’s sorting with a different comp_func. Passing comp_func in the
lsorted=andrsorted=lines fixes this: