Is list pass by value or by reference? [duplicate] - python

This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 4 years ago.
Consider the following code, at first glance it does the same thing, but the result is different, sometimes it seems list is pass by value, sometimes list seems pass by reference:
lst = [1, 2]
def f(lst):
# lst = lst + [3] # seems pass by value
# lst += [3] # strange! same as above but seems pass by reference
lst = lst.append(3) # seems pass by reference
return lst
f(lst)
print(lst)
can anyone tell me what is going on?

It’s passed by value of reference. So modifications to the object can be seen outside the function, but assigning the variable to a new object does not change anything outside the function.
It’s essentially the same as passing a pointer in C, or a reference type in Java.
The result of the += case is because that operator actually modifies the list in place, so the effect is visible outside the function. lst.append() is also an in-place operation, which explains your last case.

Related

List inheritance: "extend" vs "+" vs "+=" [duplicate]

This question already has answers here:
Why does += behave unexpectedly on lists?
(9 answers)
Different behaviour for list.__iadd__ and list.__add__
(3 answers)
Closed 3 years ago.
I would like to understand why the following three, extremely simple, python codes give (apparently) inconsistent answers. It's just a toy exercise to understand what's happening, not a real-world problem. The class myList(list) inherits from list and defines a method "add" that should mimic the well-known "extend" method. I've tried to do this in three ways, with the direct use of extend, with the + operator and with +=. However, with great surprise, I get inconsistent answers. Notice that, among the three codes, a single line (inside the add method) changes.
CODE 1: self.extend(item)
class myList(list):
def add(self,item):
self.extend(item)
l = myList([1,2])
l.add([3,4])
print(l)
Prints [1, 2, 3, 4]
CODE 2: self = self + item
class myList(list):
def add(self,item):
self = self + item
l = myList([1,2])
l.add([3,4])
print(l)
Prints [1, 2]
CODE 3: self += item
class myList(list):
def add(self,item):
self += item
l = myList([1,2])
l.add([3,4])
print(l)
Prints [1, 2, 3, 4]
I am a bit confused... what's happening?
Thank you in advance.
self = self + item
does not modify the object, only the local variable inside the method.
By using + the interpreter is calling __add__ in list, which creates a new list, and you're then making the self variable point to it within the add method, and when the method exits its value is discarded.
On the other hand, the += version calls the __iadd__ method of the list class, which updates its contents as expected.

var passed to a function by kwargs is not updated [duplicate]

This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 8 months ago.
In some languages you can pass a parameter by reference or value by using a special reserved word like ref or val. When you pass a parameter to a Python function it never alters the value of the parameter on leaving the function.The only way to do this is by using the global reserved word (or as i understand it currently).
Example 1:
k = 2
def foo (n):
n = n * n #clarity regarding comment below
square = n
return square
j = foo(k)
print j
print k
would show
>>4
>>2
showing k to be unchanged.
In this example the variable n is never changed
Example 2:
n = 0
def foo():
global n
n = n * n
return n
In this example the variable n is changed.
Is there any way in Python to call a function and tell Python that the parameter is either a value or reference parameter instead of using global?
There are essentially three kinds of 'function calls':
Pass by value
Pass by reference
Pass by object reference
Python is a PASS-BY-OBJECT-REFERENCE programming language.
Firstly, it is important to understand that a variable, and the value of the variable (the object) are two seperate things. The variable 'points to' the object. The variable is not the object. Again:
THE VARIABLE IS NOT THE OBJECT
Example: in the following line of code:
>>> x = []
[] is the empty list, x is a variable that points to the empty list, but x itself is not the empty list.
Consider the variable (x, in the above case) as a box, and 'the value' of the variable ([]) as the object inside the box.
PASS BY OBJECT REFERENCE (Case in python):
Here, "Object references are passed by value."
def append_one(li):
li.append(1)
x = [0]
append_one(x)
print x
Here, the statement x = [0] makes a variable x (box) that points towards the object [0].
On the function being called, a new box li is created. The contents of li are the SAME as the contents of the box x. Both the boxes contain the same object. That is, both the variables point to the same object in memory. Hence, any change to the object pointed at by li will also be reflected by the object pointed at by x.
In conclusion, the output of the above program will be:
[0, 1]
Note:
If the variable li is reassigned in the function, then li will point to a separate object in memory. x however, will continue pointing to the same object in memory it was pointing to earlier.
Example:
def append_one(li):
li = [0, 1]
x = [0]
append_one(x)
print x
The output of the program will be:
[0]
PASS BY REFERENCE:
The box from the calling function is passed on to the called function. Implicitly, the contents of the box (the value of the variable) is passed on to the called function. Hence, any change to the contents of the box in the called function will be reflected in the calling function.
PASS BY VALUE:
A new box is created in the called function, and copies of contents of the box from the calling function is stored into the new boxes.
You can not change an immutable object, like str or tuple, inside a function in Python, but you can do things like:
def foo(y):
y[0] = y[0]**2
x = [5]
foo(x)
print x[0] # prints 25
That is a weird way to go about it, however, unless you need to always square certain elements in an array.
Note that in Python, you can also return more than one value, making some of the use cases for pass by reference less important:
def foo(x, y):
return x**2, y**2
a = 2
b = 3
a, b = foo(a, b) # a == 4; b == 9
When you return values like that, they are being returned as a Tuple which is in turn unpacked.
edit:
Another way to think about this is that, while you can't explicitly pass variables by reference in Python, you can modify the properties of objects that were passed in. In my example (and others) you can modify members of the list that was passed in. You would not, however, be able to reassign the passed in variable entirely. For instance, see the following two pieces of code look like they might do something similar, but end up with different results:
def clear_a(x):
x = []
def clear_b(x):
while x: x.pop()
z = [1,2,3]
clear_a(z) # z will not be changed
clear_b(z) # z will be emptied
OK, I'll take a stab at this. Python passes by object reference, which is different from what you'd normally think of as "by reference" or "by value". Take this example:
def foo(x):
print x
bar = 'some value'
foo(bar)
So you're creating a string object with value 'some value' and "binding" it to a variable named bar. In C, that would be similar to bar being a pointer to 'some value'.
When you call foo(bar), you're not passing in bar itself. You're passing in bar's value: a pointer to 'some value'. At that point, there are two "pointers" to the same string object.
Now compare that to:
def foo(x):
x = 'another value'
print x
bar = 'some value'
foo(bar)
Here's where the difference lies. In the line:
x = 'another value'
you're not actually altering the contents of x. In fact, that's not even possible. Instead, you're creating a new string object with value 'another value'. That assignment operator? It isn't saying "overwrite the thing x is pointing at with the new value". It's saying "update x to point at the new object instead". After that line, there are two string objects: 'some value' (with bar pointing at it) and 'another value' (with x pointing at it).
This isn't clumsy. When you understand how it works, it's a beautifully elegant, efficient system.
Hope the following description sums it up well:
There are two things to consider here - variables and objects.
If you are passing a variable, then it's pass by value, which means the changes made to the variable within the function are local to that function and hence won't be reflected globally. This is more of a 'C' like behavior.
Example:
def changeval( myvar ):
myvar = 20;
print "values inside the function: ", myvar
return
myvar = 10;
changeval( myvar );
print "values outside the function: ", myvar
O/P:
values inside the function: 20
values outside the function: 10
If you are passing the variables packed inside a mutable object, like a list, then the changes made to the object are reflected globally as long as the object is not re-assigned.
Example:
def changelist( mylist ):
mylist2=['a'];
mylist.append(mylist2);
print "values inside the function: ", mylist
return
mylist = [1,2,3];
changelist( mylist );
print "values outside the function: ", mylist
O/P:
values inside the function: [1, 2, 3, ['a']]
values outside the function: [1, 2, 3, ['a']]
Now consider the case where the object is re-assigned. In this case, the object refers to a new memory location which is local to the function in which this happens and hence not reflected globally.
Example:
def changelist( mylist ):
mylist=['a'];
print "values inside the function: ", mylist
return
mylist = [1,2,3];
changelist( mylist );
print "values outside the function: ", mylist
O/P:
values inside the function: ['a']
values outside the function: [1, 2, 3]
Python is neither pass-by-value nor pass-by-reference. It's more of "object references are passed by value" as described here:
Here's why it's not pass-by-value. Because
def append(list):
list.append(1)
list = [0]
reassign(list)
append(list)
returns [0,1] showing that some kind of reference was clearly passed as pass-by-value does not allow a function to alter the parent scope at all.
Looks like pass-by-reference then, hu? Nope.
Here's why it's not pass-by-reference. Because
def reassign(list):
list = [0, 1]
list = [0]
reassign(list)
print list
returns [0] showing that the original reference was destroyed when list was reassigned. pass-by-reference would have returned [0,1].
For more information look here:
If you want your function to not manipulate outside scope, you need to make a copy of the input parameters that creates a new object.
from copy import copy
def append(list):
list2 = copy(list)
list2.append(1)
print list2
list = [0]
append(list)
print list
Technically python do not pass arguments by value: all by reference. But ... since python has two types of objects: immutable and mutable, here is what happens:
Immutable arguments are effectively passed by value: string, integer, tuple are all immutable object types. While they are technically "passed by reference" (like all parameters), since you can't change them in-place inside the function it looks/behaves as if it is passed by value.
Mutable arguments are effectively passed by reference: lists or dictionaries are passed by its pointers. Any in-place change inside the function like (append or del) will affect the original object.
This is how Python is designed: no copies and all are passed by reference. You can explicitly pass a copy.
def sort(array):
# do sort
return array
data = [1, 2, 3]
sort(data[:]) # here you passed a copy
Last point I would like to mention which is a function has its own scope.
def do_any_stuff_to_these_objects(a, b):
a = a * 2
del b['last_name']
number = 1 # immutable
hashmap = {'first_name' : 'john', 'last_name': 'legend'} # mutable
do_any_stuff_to_these_objects(number, hashmap)
print(number) # 1 , oh it should be 2 ! no a is changed inisde the function scope
print(hashmap) # {'first_name': 'john'}
So this is a little bit of a subtle point, because while Python only passes variables by value, every variable in Python is a reference. If you want to be able to change your values with a function call, what you need is a mutable object. For example:
l = [0]
def set_3(x):
x[0] = 3
set_3(l)
print(l[0])
In the above code, the function modifies the contents of a List object (which is mutable), and so the output is 3 instead of 0.
I write this answer only to illustrate what 'by value' means in Python. The above code is bad style, and if you really want to mutate your values you should write a class and call methods within that class, as MPX suggests.
Consider that the variable is a box and the value it points to is the "thing" inside the box:
1. Pass by reference : function shares the same box and thereby the thing inside also.
2. Pass by value : function creates a new box, a replica of the old one, including a copy of whatever thing is inside it. Eg. Java - functions create a copy of the box and the thing inside it which can be: a primitive / a reference to an object. (note that the copied reference in the new box and the original both still point to the same object, here the reference IS the thing inside the box, not the object it is pointing to)
3. Pass by object-reference: the function creates a box, but it encloses the same thing the initial box was enclosing. So in Python:
a) if the thing inside said box is mutable, changes made will reflect back in the original box (eg. lists)
b) if the thing is immutable (like python strings and numeric types), then the box inside the function will hold the same thing UNTIL you try to change its value. Once changed, the thing in the function's box is a totally new thing compared to the original one. Hence id() for that box will now give the identity of the new thing it encloses.
The answer given is
def set_4(x):
y = []
for i in x:
y.append(i)
y[0] = 4
return y
and
l = [0]
def set_3(x):
x[0] = 3
set_3(l)
print(l[0])
which is the best answer so far as it does what it says in the question. However,it does seem a very clumsy way compared to VB or Pascal.Is it the best method we have?
Not only is it clumsy, it involves mutating the original parameter in some way manually eg by changing the original parameter to a list: or copying it to another list rather than just saying: "use this parameter as a value " or "use this one as a reference". Could the simple answer be there is no reserved word for this but these are great work arounds?
class demoClass:
x = 4
y = 3
foo1 = demoClass()
foo1.x = 2
foo2 = demoClass()
foo2.y = 5
def mySquare(myObj):
myObj.x = myObj.x**2
myObj.y = myObj.y**2
print('foo1.x =', foo1.x)
print('foo1.y =', foo1.y)
print('foo2.x =', foo2.x)
print('foo2.y =', foo2.y)
mySquare(foo1)
mySquare(foo2)
print('After square:')
print('foo1.x =', foo1.x)
print('foo1.y =', foo1.y)
print('foo2.x =', foo2.x)
print('foo2.y =', foo2.y)
In Python the passing by reference or by value has to do with what are the actual objects you are passing.So,if you are passing a list for example,then you actually make this pass by reference,since the list is a mutable object.Thus,you are passing a pointer to the function and you can modify the object (list) in the function body.
When you are passing a string,this passing is done by value,so a new string object is being created and when the function terminates it is destroyed.
So it all has to do with mutable and immutable objects.
Python already call by ref..
let's take example:
def foo(var):
print(hex(id(var)))
x = 1 # any value
print(hex(id(x))) # I think the id() give the ref...
foo(x)
OutPut
0x50d43700 #with you might give another hex number deppend on your memory
0x50d43700

Types inside a function in Python. Why some gets updated but not others? [duplicate]

This question already has answers here:
Immutable vs Mutable types
(18 answers)
Closed 5 years ago.
Why does calling several times in a row the following function:
a = []
def test(a,b):
if b > 0:
a.append(1)
return a
with test(a,4), it enlarges the list a each time, but calling several times in a row the function:
a = 0
def test(a,b):
if b > 0:
a += 1
return a
with test(a,4) returns 1 every single time instead of 1, 2, 3, etc.?
It looks like lists get updated by a function and retain their updated value even after the function finished to execute, while this behavior doesn't hold for integers (and I guess floats and several other types).
Integers are immutable; lists are mutable. a += 1 changes the value of a by reassigning the value it refers to. a.append(1) adds the value 1 to the list that a refers to, without changing the reference itself.
In your test function, a if a reference within the function's scope; not the same reference as a in the global scope. However, when passing a mutable object, the reference remains the same; allowing for the object to be modified without the need to reassign the variable. In your function
def test(a, b):
if b > 0:
a += 1
return a
The value of a is modified relative to test. To reassign the value globally, you need to perform that action in the global scope (or use the global keyword). So, instead of test(a, 4), use a = test(a, 4) to reassign the value of a.

How do you create new commands in Python when immutable data types are involved? [duplicate]

This question already has answers here:
How do I pass a variable by reference?
(39 answers)
Closed 5 years ago.
In Python, the following code prints '0', not '1'.
def inc(x):
x = x+1
a = 0
inc(a)
print(a)
I understand why this happens; it's because integers are immutable. What I don't understand is how to get around this behaviour when it's undesirable. Suppose we want to create a new command such that the code
a = 0
inc(a)
print(a)
prints '1'.
Obviously, the naive approach won't do it. What can we do instead?
Similar (a bit more general) question can be found here along with a discussion how Python passes params to functions. In short, without making x variable in your code an object, I believe there's nothing we can do. Of course, you can alter your code to e.g. return changed value from function inc() and print that (i.e. print(inc(x))) or just do the printing from inside the inc() method, but that's not what you're essentially looking for.
If I understand correctly, You are trying to increment variable a using function inc(var) and passing 'a' as a external variable to the function inc().
As #Marko Andrijevic stated, variable x passed to function inc() and variable x defined in the function are different . One way to achieve is by returning value of x and collecting externally, which you may not be looking for.
Alternately, Since you have defined variable 'a' outside function ,it can be called global variable.
If you want to pass that to a function, and manipulate it, you need to define that variable ('a' in your case) inside the function as global. Something like below.
def inc(x):
global a
a = x+1
Now when the new value assigned to 'a' after 'x+1', it is retained after execution of 'inc(x)'
>>> a = 0
>>> inc(a)
>>> a
1
EDIT -1
As per comments by #DYZ . Its correct. declaring global a inside inc() function will always increment a.
A better alternative will be , in that case, to return x inside inc() and assign that value to any external variable.
Not an elegant solution, but works as intended.
def inc(x):
return x+1
Result
>>> a
0
>>> a = inc(a)
>>> a
1
>>> a = inc(a)
>>> a
2
>>> b = 0
>>> b = inc(b)
>>> b
1
>>> a
2
>>>
one can use yield to get variable values.
def inc(x,y,z):
x += 1
y+=1
z+=1
yield x,y,z #inc doesn't stop
yield x+y+z
a=b=c=0
gen=inc(a,b,c)
gen=list(gen)
a,b,c,sum=gen[0]+(gen[1],) #however, index must still be known
print a,b,c,sum

How Does Calling Work In Python? [duplicate]

This question already has answers here:
Does Python make a copy of objects on assignment?
(5 answers)
How do I pass a variable by reference?
(39 answers)
Why can a function modify some arguments as perceived by the caller, but not others?
(13 answers)
Closed last month.
For a project I'm working on, I'm implementing a linked-list data-structure, which is based on the idea of a pair, which I define as:
class Pair:
def __init__(self, name, prefs, score):
self.name = name
self.score = score
self.preferences = prefs
self.next_pair = 0
self.prev_pair = 0
where self.next_pair and self.prev_pair are pointers to the previous and next links, respectively.
To set up the linked-list, I have an install function that looks like this.
def install(i, pair):
flag = 0
try:
old_pair = pair_array[i]
while old_pair.next_pair != 0:
if old_pair == pair:
#if pair in remainders: remainders.remove(pair)
return 0
if old_pair.score < pair.score:
flag = 1
if old_pair.prev_pair == 0: # we are at the beginning
old_pair.prev_pair = pair
pair.next_pair = old_pair
pair_array[i] = pair
break
else: # we are not at the beginning
pair.prev_pair = old_pair.prev_pair
pair.next_pair = old_pair
old_pair.prev_pair = pair
pair.prev_pair.next_pair = pair
break
else:
old_pair = old_pair.next_pair
if flag==0:
if old_pair == pair:
#if pair in remainders: remainders.remove(pair)
return 0
if old_pair.score < pair.score:
if old_pair.prev_pair==0:
old_pair.prev_pair = pair
pair.next_pair = old_pair
pair_array[i] = pair
else:
pair.prev_pair = old_pair.prev_pair
pair.next_pair = old_pair
old_pair.prev_pair = pair
pair.prev_pair.next_pair = pair
else:
old_pair.next_pair = pair
pair.prev_pair = old_pair
except KeyError:
pair_array[i] = pair
pair.prev_pair = 0
pair.next_pair = 0
Over the course of the program, I am building up a dictionary of these linked-lists, and taking links off of some and adding them in others. Between being pruned and re-installed, the links are stored in an intermediate array.
Over the course of debugging this program, I have come to realize that my understanding of the way Python passes arguments to functions is flawed. Consider this test case I wrote:
def test_install():
p = Pair(20000, [3, 1, 2, 50], 45)
print p.next_pair
print p.prev_pair
parse_and_get(g)
first_run()
rat = len(juggler_array)/len(circuit_array)
pref_size = get_pref_size()
print pref_size
print install(3, p)
print p.next_pair.name
print p.prev_pair
When I run this test, I get the following result.
0
0
10
None
10108
0
What I don't understand is why the second call to p.next_pair produces a different result (10108) than the first call (0). install does not return a Pair object that can overwrite the one passed in (it returns None), and it's not as though I'm passing install a pointer.
My understanding of call-by-value is that the interpreter copies the values passed into a function, leaving the caller's variables unchanged. For example, if I say
def foo(x):
x = x+1
return x
baz = 2
y = foo(baz)
print y
print baz
Then 3 and 2 should be printed, respectively. And indeed, when I test that out in the Python interpreter, that's what happens.
I'd really appreciate it if anyone can point me in the right direction here.
In Python, everything is an object. Simple assignment stores a reference to the assigned object in the assigned-to name. As a result, it is more straightforward to think of Python variables as names that are assigned to objects, rather than objects that are stored in named locations.
For example:
baz = 2
... stores in baz a pointer, or reference, to the integer object 2 which is stored elsewhere. (Since the type int is immutable, Python actually has a pool of small integers and reuses the same 2 object everywhere, but this is an implementation detail that need not concern us much.)
When you call foo(baz), foo()'s local variable x also points to the integer object 2 at first. That is, the foo()-local name x and the global name baz are names for the same object, 2. Then x = x + 1 is executed. This changes x to point to a different object: 3.
It is important to understand: x is not a box that holds 2, and 2 is then incremented to 3. No, x initially points to 2 and that pointer is then changed to point to 3. Naturally, since we did not change what object baz points to, it still points to 2.
Another way to explain it is that in Python, all argument passing is by value, but all values are references to objects.
A counter-intuitive result of this is that if an object is mutable, it can be modified through any reference and all references will "see" the change. For example, consider this:
baz = [1, 2, 3]
def foo(x):
x[0] = x[0] + 1
foo(baz)
print baz
>>> [2, 2, 3]
This seems very different from our first example. But in reality, the argument is passed the same way. foo() receives a pointer to baz under the name x and then performs an operation on it that changes it (in this case, the first element of the list is pointed to a different int object). The difference is that the name x is never pointed to a new object; it is x[0] that is modified to point to a different object. x itself still points to the same object as baz. (In fact, under the hood the assignment to x[0] becomes a method call: x.__setitem__().) Therefore baz "sees" the modification to the list. How could it not?
You don't see this behavior with integers and strings because you can't change integers or strings; they are immutable types, and when you modify them (e.g. x = x + 1) you are not actually modifying them but binding your variable name to a completely different object. If you change baz to a tuple, e.g. baz = (1, 2, 3), you will find that foo() gives you an error because you can`t assign to elements of a tuple; tuples are another immutable type. "Changing" a tuple requires creating a new one, and assignment then points the variable to the new object.
Objects of classes you define are mutable and so your Pair instance can be modified by any function it is passed into -- that is, attributes may be added, deleted, or reassigned to other objects. None of these things will re-bind any of the names pointing to your object, so all the names that currently point to it will "see" the changes.
Python does not copy anything when passing variables to a function. It is neither call-by-value nor call-by-reference, but of those two it is more similar to call-by-reference. You could think of it as "call-by-value, but the value is a reference".
If you pass a mutable object to a function, then modifying that object inside the function will affect the object everywhere it appears. (If you pass an immutable object to a function, like a string or an integer, then by definition you can't modify the object at all.)
The reason this isn't technically pass-by-reference is that you can rebind a name so that the name refers to something else entirely. (For names of immutable objects, this is the only thing you can do to them.) Rebinding a name that exists only inside a function doesn't affect any names that might exist outside the function.
In your first example with the Pair objects, you are modifying an object, so you see the effects outside of the function.
In your second example, you are not modifying any objects, you are just rebinding names to other objects (other integers in this case). baz is a name that points to an integer object (in Python, everything is an object, even integers) with a value of 2. When you pass baz to foo(x), the name x is created locally inside the foo function on the stack, and x is set to the pointer that was passed into the function -- the same pointer as baz. But x and baz are not the same thing, they only contain pointers to the same object. On the x = x+1 line, x is rebound to point to an integer object with a value of 3, and that pointer is what is returned from the function and used to bind the integer object to y.
If you rewrote your first example to explicitly create a new Pair object inside your function based on the information from the Pair object passed into it (whether this is a copy you then modify, or if you make a constructor that modifies the data on construction) then your function would not have the side-effect of modifying the object that was passed in.
Edit: By the way, in Python you shouldn't use 0 as a placeholder to mean "I don't have a value" -- use None. And likewise you shouldn't use 0 to mean False, like you seem to be doing in flag. But all of 0, None and False evaluate to False in boolean expressions, so no matter which of those you use, you can say things like if not flag instead of if flag == 0.
I suggest that you forget about implementing a linked list, and simply use an instance of a Python list. If you need something other than the default Python list, maybe you can use something from a Python module such as collections.
A Python loop to follow the links in a linked list will run at Python interpreter speed, which is to say, slowly. If you simply use the built-in list class, your list operations will happen in Python's C code, and you will gain speed.
If you need something like a list but with fast insertion and fast deletion, can you make a dict work? If there is some sort of ID value (string or integer or whatever) that can be used to impose an ordering on your values, you could just use that as a key value and gain lightning fast insert and delete of values. Then if you need to extract values in order, you can use the dict.keys() method function to get a list of key values and use that.
But if you really need linked lists, I suggest you find code written and debugged by someone else, and adapt it to your needs. Google search for "python linked list recipe" or "python linked list module".
I'm going to throw in a slightly complicating factor:
>>> def foo(x):
... x *= 2
... return x
...
Define a slightly different function using a method I know is supported for numbers, lists, and strings.
First, call it with strings:
>>> baz = "hello"
>>> y = foo(baz)
>>> y
'hellohello'
>>> baz
'hello'
Next, call it with lists:
>>> baz=[1,2,2]
>>> y = foo(baz)
>>> y
[1, 2, 2, 1, 2, 2]
>>> baz
[1, 2, 2, 1, 2, 2]
>>>
With strings, the argument isn't modified. With lists, the argument is modified.
If it were me, I'd avoid modifying arguments within methods.

Categories

Resources