No, the situation is the same regardless of the context (and in a broader sense, regardless of what type of variable you’re dealing with). In Python, there are no value types vs. reference types, and no pass-by-reference vs. pass-by-value. Rather, every variable value is an object, every variable name a reference to an object, and there is a crucial distinction between the two—i.e., a given name, and the thing that name currently refers to.
Consider, for example, the goalkeeper of a sports team. The name “goalkeeper”, in the context of that team (i.e. that scope), refers to one given person, say, Alan, at a particular given time. However, let’s say Alan was injured while playing, and another person, Bob, was assigned to be new goalkeeper (i.e. to that name).
If we now look up to see who the “goalkeeper” is, we are now told it is Bob. However, if we know Alan by another name (for example, let’s say they are also the team captain), that name still refers to Alan, not Bob (unless we re-assign that too). Also, Bob doesn’t inherit Alan’s injury, statistics or other attributes just because he was named goalkeeper in Alan’s place, and neither does anything that happen to him as goalkeeper affect Alan.
In code, we can represent the situation something like this:
alan = Player("Alan")
bob = Player("Bob")
goalkeeper = alan
captain = alan
goalkeeper.injure()
goalkeeper = bob
assert goalkeeper is bob
assert captain is alan
assert alan.injured
assert not bob.injured
Applying this to your situation. you have a list object, [3, 4, 5]
, that you’ve given the name a
. If you then create a new list object [5, 6]
and assign that new object to the name a
, what the name refers to changes (like who was currently called the goalkeeper
), but the original list object (like Alan, the person who was original goalkeeper) doesn’t change simply by giving something else that name. If you also knew the list a
by another name, say original_list
in
original_list = [3, 4, 5]
a = original_list
a = [5, 6]
then original_list
(like the team captain) doesn’t change just because you reassigned another object to a
(like another person to goalkeeper).
If you instead modify the original object, i.e.
a[:] = [5, 6]
just like injuring a goalkeeper, you’re modifying the object itself in place, not just what is assigned to its name, and so other names for that object (like original_list
) will reflect those changes.
Actually no, it doesn’t modify the list, as you’ve now learned. Rather, it creates a new list object, and then assigns it the same name as the previous one. Does that make sense now?