Reputation: 529
I'm from a C++ background so this problem seems a little absurd to me: Let's suppose I have a function:
def scale(data, factor):
for val in data:
val *= factor
This doesn't work as intended, if I pass a list, it changes nothing, but
def scale(data, factor):
for index, val in enumerate(data):
data[index] *= factor
and lst = [val * factor for val in lst]
works properly.
How does Python handle argument passing? How do I know if the actual reference, or alias is passed?
Upvotes: 0
Views: 73
Reputation: 9624
This behaviour is so because the basic data types are passed by value and the derived data types like lists are passed by reference consider this
>>> x = 24
>>> x + 1
25
>>> x
24
but on the otherhand with a list
>>> y = [1, 2, 3, 4]
>>> y.remove(2)
>>> y
[1,3,4]
so you should always be careful to reassign values back when performing operations on them in the case of the basic data ypes and also be careful with datatypes that are passed by reference because you could accidentally modify a variable without knowing
Upvotes: 1
Reputation: 5759
if you want to mutate the list, you need to reference the elements. This version uses map
(it could be written using list comprehensions)
def scale(data, factor):
return map(lambda x : x*factor, data)
a lambda function is an anonymous
function.
>>> (lambda x : x + 1) (5)
6
The x
takes the place of the variable in this case 5 + 1
So in this case, we traverse the list applying the function f(x) -> x * factor
to every element of the list. The original list is not mutated, but instead we return a new version.
Upvotes: 4
Reputation: 3317
In python basic data types are passed by value - for example int
, str
, bool
etc are passed by value
Derived data types like classes
, enum
, list
, dict
are passed by reference.
In your example, the problem is how you use the for loop - not the function argument. If you do:
for val in lst:
val += 1
The values inside lst won't get updated because the val
is not the same as lst[0]
, lst[1]
and so on IF val
is of the basic data types. So, even here, the val
is copied by value.
Second, In your example with enumerate
:
But when you loop over the enumerated
list, you are using data[index]
- which modifies the element in the actual list.
And finally, In your example with the generator:
lst = [val * factor for val in lst]
- here the generator loops over every element and creates a new list which is again stored in lst
. This is something like a = a + 2
but extended to lists.
Upvotes: 3