Infinite Loop solution ... .append( ) vs +

Learning about Infinite Loops is making my brain go loopy! Trying to make sense of Codecademy’s solution code in the link below …
https://www.codecademy.com/courses/learn-python-3/lessons/learn-python-loops/exercises/infinite-loops

The instruction is to combine students from students_period_A with students_period_B …
students_period_A = [“Alex”, “Briana”, “Cheri”, “Daniele”]
students_period_B = [“Dora”, “Minerva”, “Alexa”, “Obie”]

My answer was simply …
students_combined = students_period_A + students_period_B
print(students_combined)

…and when I printed my above code, I thought the answer looked great!

But the solution from Codecademy, because I’m on the topic of Infinite Loops is …
for student in students_period_A:
students_period_B.append(student)
print(student)

… BUT the print shows only the names from students_period_A. Isn’t that wrong?! The instruction is to combine students from BOTH period A and B!

The Codecademy code solution makes no sense to me and the print result looks wrong to me!

What’s going on? Someone help?

The instructions specify:

Suppose we have two lists of students, students_period_A and students_period_B. We want to combine all students into students_period_B.

The instructions want the students from period A to be added to the existing list students_period_B.

You have created a new list students_combined instead of adding the A students to the existing B list.
Yes, you have successfully combined the two lists, but the automated system is very particular and most probably checks whether students_period_B has been updated correctly.

You could be tempted to do:

students_period_B = students_period_B + students_period_A

This will combine the students and save the result to student_period_B. But technically, you have created a new list. I don’t know whether the system will accept it or not.

If you append the A students to students_period_B, then you aren’t creating a new list. You are modifying/mutating the already existing list.

for student in students_period_A:
    students_period_B.append(student)
    print(student)

You are only seeing the names from the A list, because student is iterating over the list students_period_A and the student is printed via the statement print(student). Nevertheless, after the loop finishes, you will have a list which has combined students from both lists. You can confirm this by adding a print statement after the for loop:

print(students_period_B)

You will see the combined students from both the B and A lists.

Also, if you have python installed (if not, you can use an online editor), you may want to play around with creating vs mutating lists:

x = [1, 2, 3]
print(id(x))
54697224  # You will see other numbers on screen 
x = x + [4]
print(x)
[1, 2, 3, 4]  
print(id(x))
27578632  # Different id. New list was created.

_________________

x = [1, 2, 3]
print(id(x))
59431976     # You will see other numbers on screen 
x.append(4)
print(x)
[1, 2, 3, 4]
print(id(x)) 
59431976    # Same id as before append. The same list was mutated.

# In both cases, we end up with the same list x = [1, 2, 3, 4] but
# in the first case, we created a new list. In the latter, we 
# mutated the existing list.

# EDIT: The += doesn't create a new list.
x = [1, 2, 3]
print(id(x))
61444008
x += [4]
print(x)
[1, 2, 3, 4]
print(id(x))
61444008  # Same id after as before using +=

# x = x + [4] will create new list
# x += [4] will modify existing list
# x.append(4) will modify existing list  

Thank you mtrtmk for your super detailed and organized response. I am beginning to better understand the importance and difference between creating a new list and modifying an existing list as a result of different coding methods.

I think I understand everything that you wrote except for the very end examples where you coded … print(id(x)). What does id stand for? This is throwing my brain in for a malfunctioning infinite loop (pun or no pun intended)?!

Sorry. Me again. I went back to the Infinite Loops tutorial page to enter what I thought was my newfound understanding of this concept. But then it doesn’t make sense anymore.

This is the wrong and bad infinite loop code …
for student in students_period_A:
students_period_A.append(student)
print(student)

… I am assuming the print output will look something like below …
[“Alex”, “Briana”, “Cheri”, “Daniele”]
[“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”]
[“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”, “Briana”]
[“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”, “Briana”, “Cheri”]
[“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”, “Briana”, “Cheri”, “Daniele”]
[“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”]

… and on and on … cycling through the names and adding the next one to the end of the list. Ok got that.

BUT, the correct code to the instruction as seen below …
for student in students_period_A:
students_period_B.append(student)
print(students_period_B)

… what makes the print output stop at the fourth iteration …
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’, ‘Daniele’]

… why not keep looping and going back on like below …
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’, ‘Daniele’, ‘Alex’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’, ‘Daniele’, ‘Alex’, ‘Briana’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’, ‘Daniele’, ‘Alex’, ‘Briana’, ‘Cheri’]

… and on and on … continuing to cycle through the student names from period A? I guess I am not completely getting the difference between the wrong and bad code vs the correct code. Why does the wrong and bad code keep adding the next name from the list of four from students_period_A to the end of the list … but the correct code just stops at the end of the fourth name from students_period_A?

From the documentation for id (https://docs.python.org/3/library/functions.html#id),

Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime. Two objects with non-overlapping lifetimes may have the same id() value.

CPython implementation detail: This is the address of the object in memory.

The motivation for the last example was to show that if we have a list x = [1, 2, 3] and we concatenate another list to this list in the form x = x + [4], then the original list isn’t being modified. Rather, a new list is created, The different ids of x before and after concatenation confirm that x is not the same object.
In contrast, if we append e.g. x.append(4) or use x += [4], then we aren’t creating new lists but modifying/mutating the original list. The ids of x before and after these operations is the same which means that we didn’t create new objects; we just modified the existing object.

The id is basically giving us the memory address where the object/list is stored in memory. If we are modifying an object, then the memory address remains unchanged. If we are creating a new object, then the new object will be created at a different memory location. If you want to see the hexadecimal representation of the memory, you can do print(hex(id(x)))
If I create a list x = [1, 2, 3], the list will be stored at some memory location. If I again type x = [1, 2, 3], another list will be created at some other location. That is why the ids are different. If I merely mutate the list, memory location and consequently id stay the same.

Oh. This id concept is advanced stuff that I haven’t learned yet. Thank you. I will save your explanation of id to reference when my tutorial reaches this level.

I went back to the Infinite Loop tutorial page to enter my newfound knowledge of the correct solution code that your explained. But then, I realize I don’t fully understand because the below is throwing me in for yet another brain loop (there is that pun again).

The wrong/bad code is …
for student in students_period_A:
students_period_A.append(student)
print(student)

… I get why this is an infinite loop situation because the print output would continue to produce line after line of the students_period_A list with the addition of the next student name at the end of the list … over and over again.

BUT, the correct solution code is …
for student in students_period_A:
students_period_B.append(student)
print(students_period_B)

… WHY wouldn’t the same infinite loop situation occur like in the wrong/bad code? In my mind, the print output would look something like …
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’, ‘Daniele’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’, ‘Daniele’, ‘Alex’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’, ‘Daniele’, ‘Alex’, ‘Briana’]
[‘Dora’, ‘Minerva’, ‘Alexa’, ‘Obie’, ‘Alex’, ‘Briana’, ‘Cheri’, ‘Daniele’, ‘Alex’, ‘Briana’, ‘Cheri’]

… and on and on … where the print output is infinite because the students_period_B list would just cycle through the students_period_A names over and over again and add it to the end of the students_period_B list.

Help?

students_period_A = ["Alex", "Briana", "Cheri", "Daniele"]
students_period_B = ["Dora", "Minerva", "Alexa", "Obie"]

INFINITE LOOP CODE:

for student in students_period_A:
    students_period_A.append(student)
    print(student)

First Iteration of loop: student will be first element “Alex” and
students_period_A will become [“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”]

Second Iteration of loop: student will be second element “Briana” and
students_period_A will become [“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”, “Briana”]

Third Iteration of loop: student will be third element “Cheri” and
students_period_A will become
[“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”, “Briana”, “Cheri”]

Fourth Iteration of loop: student will be fourth element “Daniele” and
students_period_A will become
[“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”, “Briana”, “Cheri”, “Daniele”]

Fifth Iteration of loop: student will be fifth element “Alex” and
students_period_A will become
[“Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”, “Briana”, “Cheri”, “Daniele”, “Alex”]

and this will continue forever. In every iteration, we are moving one step forward, but we are appending a new element/student in every iteration. We will never get to the end of a list which keeps growing. We are iterating over students_period_A and yet we keep appending to the same list. We will never get to the last element of this list because we keep adding a new element.

CORRECT LOOP CODE:

for student in students_period_A:
    students_period_B.append(student)
    print(student)

First Iteration of loop: student will be first element of list A “Alex” and
students_period_B will become [“Dora”, “Minerva”, “Alexa”, “Obie”, “Alex”]

Second Iteration of loop: student will be second element of list A “Briana” and
students_period_B will become [“Dora”, “Minerva”, “Alexa”, “Obie”, “Alex”, “Briana”]

Third Iteration of loop: student will be third element of list A “Cheri” and
students_period_B will become
[“Dora”, “Minerva”, “Alexa”, “Obie”, “Alex”, “Briana”, “Cheri”]

Fourth Iteration of loop: student will be fourth element of list A “Daniele” and
students_period_B will become
[“Dora”, “Minerva”, “Alexa”, “Obie”, “Alex”, “Briana”, “Cheri”, “Daniele”]

And that’s it.
We have looped over every single student in students_period_A and so the for loop will finish. The for loop doesn’t keep going in circles. The for loop iterates over every element of a list from the first to the last element.
students_period_A had 4 students. The for loop will iterate over all four of them and then stop because it has gotten to the end of the list,

At this point after the loop has finished, if we use print statements, we will see

for student in students_period_A:
    students_period_B.append(student)
    print(student)
print(students_period_A)
print(students_period_B)

print(students_period_A)
Output: [“Alex”, “Briana”, “Cheri”, “Daniele”]
Unchanged list

print(students_period_B)
Output: [“Dora”, “Minerva”, “Alexa”, “Obie”,“Alex”, “Briana”, “Cheri”, “Daniele”]
Mutated list with four new elements

2 Likes

Yes! I got it! Thank you mtrtmk for your time in explaining this so clearly to me!

1 Like