How exactly does the loop within a bubble sort algorithm work? (Python 3)

Question:

Example code:

def bubble_sort(my_list):
    n = len(my_list)

    for i in range(n):
        for j in range(0, n - 1 - i):
            if my_list[j] > my_list[j + 1]:
                my_list[j], my_list[j + 1] = my_list[j + 1], my_list[j]


my_list = [94, 17, 5, 28, 7, 63, 44]
bubble_sort(my_list)
print(my_list)

In the code above, I am confused about the for for __ in range() part of the nested loop. What does this do and how does it do it? Also, how does my_list[j], my_list[j+1] = my_list[j+1], my_list[j] rearrange the the list values? Sorry if this sounds dumb, but I want to understand the logic behind the syntax I’m writing, and I couldn’t find a place that explained the logic well, so hopefully someone who sees this can. Thanks for any help!

Asked By: user10369370

||

Answers:

Nice questions. I’ll try to address the two questions I detected in your post.

Question 1: What does for __ in range()? The range function simply generates a list of numbers. For instance, assuming n = 5, then range(5) is equal to range(n), which in return generates [0, 1, 2, 3, 4]. The length of this list is 5, 0 being inclusive and 5 being exclusive. Since lists are iterables in python, the for loop iterates the list.

For example:

for i in range(5): print(i, end=' ')

Will print 0 1 2 3 4

Being said all this, what does the nested loop does? Well, the first thing to notice is that in this case, the range starts at zero (0), that is why you have range(0, …. What is really confusing is the second part inside the range function. In order to understand why this is like this, we need to understand how the bubble sort behave.

Taking the input list as example:

my_list = [94, 17, 5, 28, 7, 63, 44]

The bubble sort will sort like this:

[17, 5, 28, 7, 63, 44, 94]
[5, 17, 7, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]
[5, 7, 17, 28, 44, 63, 94]

Now, notice something really interesting about the way the bubble sort is organizing the list. What is doing is that is taking the largest number and putting it at the end of the list (94), then it takes the 2nd largest number and putting it next to the 94 in order (63), and so on. Virtually, our list contains two sides the ordered side and the unordered side. Since we have items that have been ordered already, there is no reason to iterate those. That is why you have the – i in the expression n – 1 – i.

Now, why doing the subtraction of -1 you may ask. The reason is the swapping which belong to the second question to asked.

Question 2: How the heck this (my_list[j], my_list[j + 1] = my_list[j + 1], my_list[j]) rearrange my items?

The code above is equivalent to doing this in other languages:

int temp = item[i];
item[i] = item[i + 1];
item[i + 1] = temp;

To better understand this, we need to understand how variables work in programming. As its name states, variables are what they say they are, variables, meaning their value may change. If you assign a value to a variable, and then you assign another value to the same variable, the previous value will be wiped out.

Since we need to put the value of item[i] inside item[i + 1], it would be incorrect to do this

item[i] = item[i + 1]

because then how can we assign

item[i + 1] = item[i]

since we wiped out the previous value in item[i]. In that case, the approach to take is to use a temporal variable that is used to hold the value of one of the “containers” in order for us to the swap successfully. The only thing is that python does this beautifully by using syntactic sugar and enabling programmers to do swapping values by just typing something like:

(my_list[j], my_list[j + 1] = my_list[j + 1], my_list[j]) 

In conclusion, for the second question, we add -1 because we want to swap the last and the second to last without getting and IndexError.

Answered By: Armando Perez