Skip to content Skip to sidebar Skip to footer

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(list

Solution 1:

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

No, that is not what happens.

What happens is that, when you execute mylist = mylist + [6], you are effectively creating an entirely new list and putting it in the local mylist variable. This mylist variable will vanish after the execution of the function and the newly created list will vanish as well.

OTOH when you execute mylist.append(6) you do not create a new list. You get the list already in the mylist variable and add a new element to this same list. The result is that the list (which is pointed by list2 too) will be altered itself. The mylist variable will vanish again, but in tis case you altered the original list.

Let us see if a more visual explanation can help you :)

What happens when you call proc()

When you write list1 = [1, 2, 3, 4, 5] you are creating a new list object (at the right side of the equals sign) and creating a new variable, list1, which will point to this object.

Creating new list instance and global variable

Then, when you call proc(), you create another new variable, mylist, and since you pass list1 as parameter, mylist will point to the same object:

Calling method creates local variable

However, the operation mylist + [6]creates a whole new list object whose contents are the contents of the object pointed by mylist plus the content of the following list object - that is, [6]. Since you attribute this new object to mylist, our scenario changes a bit and mylist does not point to the same object pointed by list1 anymore:

mylist points to new list object

What I have not said is that mylist is a local variable: it will disappear after the end of the proc() function. So, when the proc() execution ended, the mylist is gone:

mylist is gone

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

GC collects the list

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

What happens when you call proc2()

Everything changes when you call proc2(). At first, it is the same thing: you create a list...

Creating new list instance and global variable

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

Calling method creates local variable

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

Appending a value to a list

After the end of the function, the local variable will disappear, but the original object pointed by it and by list1 will be already altered:

It is still altered

Since it is still pointed by list1, the original list is not destroyed.

EDIT: if you want to take a look at all this stuff happening before your eyes just go to this radically amazing simulator:

enter image description here

* If you do not know what is garbage collector... well, you will discover soon after understanding your own question.

Solution 2:

Variables in python can always be thought of as references. When you call a function with an argument, you are passing in a reference to the actual data.

When you use the assignment operator (=), you're assigning that name to refer to an entirely new object. So, mylist = mylist + [6] creates a new list containing the old contents of mylist, as well as 6, and assigns the variable mylist to refer to the new list. list1 is still pointing to the old list, so nothing changes.

On the other hand, when you use .append, that is actually appending an element to the list that the variable refers to - it is not assigning anything new to the variable. So your second function modifies the list that list2 refers to.

Solution 3:

Ordinarily, in the first case in function proc you would only be able to change the global list by assignment if you declared

global mylist

first and did not pass mylist as a parameter. However, in this case you'd get an error message that mylist is global and local: name 'mylist' is local and global. What happens in proc is that a local list is created when the assignment takes place. Since local variables go away when the function ends, the effect of any changes to the local list doesn't propagate to the rest of the program when it is printed out subsequently.

But in the second function proc2 you are modifying the list by appending rather than assigning to it, so the global keyword is not required and changes to the list show elsewhere.

Solution 4:

As well as the comprehensive answers already given, it's also worth being aware that if you want the same looking syntax as:

mylist = mylist + [6]

...but still want the list to be updated "in place", you can do:

mylist += [6]

Which, while it looks like it would do the same thing as the first version, is actually the same as:

mylist.extend([6])

(Note that extend takes the contents of an iterable and adds them one by one, whereas append takes whatever it is given and adds that as a single item. See append vs. extend for a full explanation.)

Solution 5:

This, in one form or another, is a very common question. I took a whack at explaining Python parameter passing myself a couple days ago. Basically, one of these creates a new list and the other modifies the existing one. In the latter case, all variables that refer to the list "see" the change because it's still the same object.

Post a Comment for "Why Does Not The + Operator Change A List While .append() Does?"