Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does one function work and other don't ? How is the mutability or immutability working here?

Suppose I have a list as such li = [1, 2, 3, 4, 5] and a scale function as

def scale(data, factor):
    for j in range(len(data)):
        data[j] *= factor

Now if I pass li to scale function with a factor = 2, my list gets modified. That is the actual parameter gets changed here. So if i print li after executing the above function it gives [2, 4, 6, 8, 10] and not the original one.

Another way scale function is implemented is as follows:-

def scale(data, factor):
    for val in data:
        val *= factor

Now if I execute scale(li, 2) then it doesn't modify the actual parameter. So li stays as [1, 2, 3, 4, 5]. So my question is why does one modify the list and the other doesn't? Has this got anything to do with mutability or immutability?

like image 559
saurav Avatar asked Oct 15 '25 06:10

saurav


2 Answers

data[j] *= factor is the same as data[j] = data[j] * factor so you are modifying data object. This operation calls __setitem__ method of list data, which puts the result of data[j] * factor into the corresponding position.

When you do for val in data: in val is stored a reference to an item in data. That item (object) doesn't not know anything about the list data it was taken from. You are now working only with the item itself, not the list which contains another reference to it (along with val).

val *= factor creates a new object (the result of the product) and puts a reference to it into variable val. data still contains a reference to the old object/value which was in val before the assignment.

See more here: https://stackoverflow.com/a/8140747/248296

like image 141
warvariuc Avatar answered Oct 17 '25 21:10

warvariuc


In the second example, the for loop creates a variable val=1 (and so on). When you do val = val * factor, the value of val changes. However, this has no connection to the original list[0]. You are just changing a temporary variable val

On the first example however, you do list[0] = list[0] * factor, so the assignment is done to the list itself.

I wouldn't say that it's so much a matter of mutability/immutability here (the right hand of both assignments is the same, and multiplies an immutable object in both cases). Mutability would be an issue if, eg, in the second example, you were passing val instead of data to your function, and change its value. In that case, the original value would not change, because val would be immutable.

like image 38
blue_note Avatar answered Oct 17 '25 20:10

blue_note



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!