Recall that we can add lists as follows:
L1 = [1, 2]
L2 = [4, 5]
L = L1 + L2
What happens is that we compute L1 + L2 (the result is [1, 2, 4, 5]), place the result in memory, and then assign the address of the result to L.
We can, of course, also assign the result to L1 using L1 = L1 + L2. Let's explore this a little bit:
L1 = [1, 2]
L2 = [4, 5]
print("id(L1) =", id(L1), "L1 =", L1)
L1 = L1 + L2
print("id(L1) =", id(L1), "L1 =", L1)
The address to which L1 refers changed. It should have: we created a new object (a list with the contents [1, 2, 4, 5]), and placed it in a new available location in memory, and then assigned the address of that location back to L1.
Another thing we could do was use list.extend:
L1 = [1, 2]
L2 = [4, 5]
print("id(L1) =", id(L1), "L1 =", L1)
L1.extend(L2)
print("id(L1) =", id(L1), "L1 =", L1)
L1.extend(L2) modifies the contents of L1, but keeps its address the same.
Here is where it matters:
def add_lists_bad(L1, L2):
#modify what the local variable L1
#refers to: won't matter outside the function
L1 = L1 + L2
def add_lists_good(L1, L2):
#modify the contents of the list that L1
#refers to. Will make a difference outside
#the function
L1.extend(L2)
if __name__ == '__main__':
L1 = [1, 2]
L2 = [4, 5]
add_lists_bad(L1, L2)
print("L1 after add_lists_bad:", L1)
add_lists_good(L1, L2)
print("L1 after add_lists_good:", L1)
If we want the function to have an effect on the global variable, we need to modify its content, not assign something new to its alias.
Even though it seems like L1 += L2 should be equivalent to L1 = L1 + L2, due to a design quirk, it is actually equivalent to L1.extend(L2).