pythonlistappendconcatenation

Why does not the + operator change a list while .append() does?


I'm working through Udacity and Dave Evans introduced an exercise about list properties

list1 = [1,2,3,4]
list2 = [1,2,3,4]

list1=list1+[6]
print(list1)
list2.append(6)
print(list2)

list1 = [1,2,3,4]
list2 = [1,2,3,4]

def proc(mylist):
    mylist = mylist + [6]

def proc2(mylist):
    mylist.append(6)

# Can you explain the results given by the four print statements below? Remove
# the hashes # and run the code to check.

print (list1)
proc(list1)
print (list1)

print (list2)
proc2(list2)
print (list2)

The output is

[1, 2, 3, 4, 6]
[1, 2, 3, 4, 6]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4, 6]

So in a function the adding a 6 to the set doesn't show but it does when not in a function?


Solution

  • When you execute mylist = mylist + [6], you're actually creating an entirely new list and assigning it to the local variable mylist. This local variable mylist will disappear after the function completes, and the newly created list will also vanish.

    On the other hand, when you execute mylist.append(6), you don't create a new list. Instead, you modify the existing list that mylist is pointing to by adding a new element to it. This change is reflected in the original list (which list2 also points to). The mylist variable will still disappear after the function ends, but in this case, the original list remains altered.

    Let's break this down visually:


    What Happens When You Call proc()

    When you write list1 = [1, 2, 3, 4, 5], you're creating a new list object (on the right side of the equals sign) and assigning it to a new variable, list1, which points to this object.

    Creating new list instance and global variable

    When you call proc(), a new variable mylist is created. Since you pass list1 as a parameter, mylist points to the same object:

    Calling method creates local variable

    However, the operation mylist + [6] creates a new list object that combines the elements of the object pointed to by mylist with [6]. Since this new list is assigned to mylist, the situation changes, and mylist no longer points to the same object as list1:

    mylist points to new list object

    Remember, mylist is a local variable that will disappear after proc() ends. So, when the function execution is complete, mylist is gone:

    mylist is gone

    Since no other variable points to the object created by mylist + [6], it will disappear too (collected by the garbage collector):

    GC collects the list

    Notice that in the end, the object pointed to by list1 is not changed.


    What Happens When You Call proc2()

    The scenario changes when you call proc2(). Initially, it's the same: you create a list...

    Creating new list instance and global variable

    ...and pass it as a parameter to a function, which generates a local variable:

    Calling method creates local variable

    However, instead of using the + operator (which generates a new list), you use the append() method. The append() method does not create a new object; it modifies the existing one:

    Appending a value to a list

    After the function ends, the local variable will disappear, but the original list pointed to by both mylist and list1 remains altered:

    It is still altered

    Since list1 still points to this list, the original list is not destroyed.


    EDIT: If you want to see all of this in action, check out this amazing simulator:

    enter image description here

    * If you're unfamiliar with garbage collection, you'll soon understand it better after grasping this concept.