Hi all,
I’ve been following a Python course from thegreatcourses.com and towards the middle of the 21st lecture, an example of a recursive function is given, and I cannot for the life of me work out why it calls itself or even how it’s supposed to achieve what it sets out to do.
The course is paid so I can’t link the video, but I’ll do my best to describe what the function is supposed to do, and then I’ll post the code.
Basically the function takes a list as it’s only parameter and then divides it in two, storing the leading half of it’s elements in one variable and the rest in another. It then recursively calls itself two times, passing the first half of the list to the first call, and the second half of the list to the second call. Finally it calls a separately defined merge()
function, passing in each half of the list.
merge()
merges the two halves of the list (which at this point are supposedly sorted, although I can’t quite work out how this is meant to have happened). There’s an accompanying materials pack with the course that contains a list of any errors that the producers noticed after the video was made, but they don’t mention anything about it in there. Anyway, here is the code.
def mergeSort(l):
n = len(l)
# if the input list has only one element, or is empty, there is no need to sort, so return
if n <= 1:
return
# divide the input list into two lists
l1 = l[:n//2]
l2 = [n//2:]
# recursive calls, passing in the two halves of the divided list
mergeSort(l1)
mergeSort(l2)
# merge the elements of the two halves of the divided list into one list
merge(l1, l2, l)
def merge(a, b, c):
'''merge list a and list b into list c'''
i = 0 # counter to track the index of the element in the merged list c who's value is
# being calculated for a given iteration of the while loop
j = 0 # counter to track the index of the element in a, being considered for c, in a given
# iteration of the loop
k = 0 # counter to track the index of the element in b, being considered for c, in a given
# iteration of the loop
# while at least one of j or k is a valid index into it's respective list, run the loop
while j < len(a) or k < len(b):
if j < len(a):
if k < len(b):
# both indices are valid - we haven't consumed all the element of either.
# Compare a[j] and b[k], adding the element with the smallest value to
# the final list
if a[j] < b[k]:
c[i] = a[j]
j += 1
else:
c[i] = b[k]
k += 1
else:
# we've consumed all elements of b, add the next element of a to the final list
c[i] = a[j])
j += 1
else:
# we've consumed all elements of a, add the next element of b to the final list
c[i] = b[k]
k += 1
i += 1
I know merge()
isn’t very pythonic, I think the reason for that is that the particular section in question of the course addresses algorithms, specifically writing them out using pseudo-code and then implementing them. It’s not stated explicitly, but I get the impression that during this section of the course the focus shifts slightly from pure Python to teaching a general computer science concept, using Python as a vehicle to do so.
Anyway, I fully understand the merge()
routine, what I don’t understand is how the lists given to merge()
become sorted, I can only imagine it’s got something to do with the mutability of l
(the initial list passed into the first call to mergeSort()
). Either way the course material doesn’t go very far out of it’s way to explain what’s actually going on here.
I’ve copied the example from the course perfectly, save for changing the name of a few variables to something that I felt was easier to follow, but if anyone wants to see a screenshot of the code in the lecture video I’m happy to provide.
Any help is appreciated as always.