Home > other >  Selection Sort in Python working in place
Selection Sort in Python working in place

Time:06-09

I have written this selection sort algorithm which works "in place". I want to sort the following list: [8,3,1,7,4,10,5,9,2,6]. When I run the algorithm I get the following output: [10, 2, 3, 4, 5, 6, 7, 8, 9, 10].

def selectionSortInPlace(listToSort):
    index = 0
    for i in range(0, len(listToSort)):
        value = listToSort[i]
        index = 0
        for j in range(i 1, len(listToSort)):
            if listToSort[j] < value:
                value = listToSort[j]
                index = j
        temp = listToSort[i]
        listToSort[i] = value
        listToSort[index] = temp
    
unsortedList = [8,3,1,7,4,10,5,9,2,6]
selectionSortInPlace(unsortedList)
print(unsortedList)

CodePudding user response:

Your bug is that you set index = 0 and value = listToSort[i], and proceed with the swap even if the for loop didn't update those values.

One way to fix this would be to set these values to None and then continue the loop if they don't have real values:

def selectionSortInPlace(listToSort):
    for i in range(0, len(listToSort)):
        value = None
        index = None
        for j in range(i 1, len(listToSort)):
            print(j)
            if listToSort[j] < value:
                value = listToSort[j]
                index = j
        if index is None:
            continue
        temp = listToSort[i]
        listToSort[i] = value
        listToSort[index] = temp

Another option would be to set index = i so that it stays synchronized with value even if the for loop never updates either (this simply makes the swap a no-op in that case):

def selectionSortInPlace(listToSort):
    for i in range(0, len(listToSort)):
        index = i
        value = listToSort[i]
        for j in range(i 1, len(listToSort)):
            print(j)
            if listToSort[j] < value:
                value = listToSort[j]
                index = j
        temp = listToSort[i]
        listToSort[i] = value
        listToSort[index] = temp

You can simplify the code a bit by making use of enumerate (which lets you iterate over the index and the value automatically rather than having to iterate by index and then look up the value), and tuple assignment (which lets you do the swap without a temp variable):

def selectionSortInPlace(listToSort):
    for i, a in enumerate(listToSort):
        k = i
        for j, b in enumerate(listToSort[i 1:], i 1):
            if b < a:
                k, a = j, b
        listToSort[i], listToSort[k] = listToSort[k], listToSort[i]

You can make it even simpler using the min function, since that will automatically do the inner iteration to find the smallest value for you:

def selectionSortInPlace(listToSort):
    for i, _ in enumerate(listToSort):
        j, _ = min(enumerate(listToSort[i:], i), key=lambda j_: j_[1])
        listToSort[i], listToSort[j] = listToSort[j], listToSort[i]
  • Related