*CASE A :
list=[0, 1, 2, 3]
list_copy=list
list=list+[4]
print(“list is ”,list)
print(“list_copy is “, list_copy)
—————
Print output :
list is [0, 1, 2, 3, 4]
list_copy is [0, 1, 2, 3]
—————
(this non-mutating behavior also happens when concatenating a list of more than a single entry, and when 'multiplying' the list, e.g. list=list*2)
In this case the original list object that “list” pointed to has not been altered in memory and list_copy still points to it, another object has simply been created in memory for the result of the concatenation that “list” now points to (there are now two distinct, different list objects in memory)
———————————————
*CASE B:
list=[0, 1, 2, 3]
list_copy=list
list.append(4)
print("list is ", list)
print("list_copy is ", list_copy)
——————
Outputs :
list is [0, 1, 2, 3, 4]
list_copy is [0, 1, 2, 3, 4]
____________________________
*CASE C:
list=[0, 1, 2, 3]
list_copy=list
list[-1]="foo"
print("list is ", list)
print("list_copy is ", list_copy)
—————————————
Outputs :
list is [0, 1, 2, 'foo']
list_copy is [0, 1, 2, 'foo']
—————————————
In case B and C the original list object that “list” points to has mutated, list_copy still points to that same object, and as a result the value of list_copy has changed. (there is still one single list object in memory and it has mutated).
This behavior seems inconsistent to me as a noob. Is there a good reason/utility for this?
The '+' operator is emulating the behavior for numerical types by design. I'm guessing it is not mutating lists because that is the behavior you would expect when you use the operator on ints for example. I'm guessing this behavior is also consistent (by convention) across all usages of the '+' operator.
In case anyone stumbles upon this question, in addition to Stephen's answer here, there's a link that gives excellent explanations to questions regarding the topic of mutations in python :
www-inst.eecs.berkeley.edu/~selfpace/cs9honline/Q…
Also I've asked this question over on stackoverflow and got some interesting answers as well. Here's an edit I added to my original question over there to summarize the answers :
-In python mutating operations are explicit
-The addition or multiplication operator performed on list objects creates a new object, and doesn't change the list object implicitly
[Both of these "facts" are the reasons why alist=alist+[5] won't mutate alist, whereas alist+=[5] will]
I could also add:
-"Every time you use square brackets to describe a list, that creates a new list object"
[this from : www-inst.eecs.berkeley.edu/~selfpace/cs9honline/Q… ]
Also I realized after Kabanus' answer how careful one must be tracking mutations in a program :
and
Will yield completely different values for z. This must be a frequent source of errors isn't it?
I'm only in the beginning of my learning and haven't delved deeply into OOP concepts just yet, but I think I'm already starting to understand what the fuss around functional paradigm is about...