fatg
fatg

Reputation: 529

How do I properly pass an argument to a function

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

Answers (3)

danidee
danidee

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

beoliver
beoliver

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

AbdealiLoKo
AbdealiLoKo

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

Related Questions