0

I'm kind of new to Python, and am having trouble understanding what "=" means. I will try and describe my current model of what it means, and then point out where it breaks.

My current model of "=" is that when we write A = B, we have A a reference, and B another reference (because "everything is a reference"). The operation "=" makes A point to the same object as B.

e.g

x = [1,2]
y = x

would have both x and y as references which point to the same list object. It (kind of) makes sense to me that

x[0] = 1

mutates x, as x is a "list of references" and the "=" operator has changed which object x[0] is pointing to. Under the same model,

myobj.a = 2

causes the value of a to change, as myobj.a is a reference which we are causing to point to "2". However, in numpy we can edit arrays in place using "fancy indexing":

import numpy as np
arr1 = np.array([1,2])
arr2 = np.array([0,0,0,0])
arr2[arr1] = np.array([1,1])

The value of arr2 is now [0,1,1,0]. This does not make sense to me, as under my previous model arr[arr1] is a reference pointing towards a "view" of arr2. How can assigning to this reference cause mutation in arr2? I'm not quite sure where the hole in my understanding is here.

I've found learning Python slightly frustrating as I can't seem to get a good "model of execution". I would love advice on how to get a better mental model of the language.

  • `s = [1,2,3,4,5]; s[1:3] = [9,8,7];` results in `s` being `[1,9,8,7,4,5]` - that is how slicing assignments work. – luk2302 Feb 18 '22 at 14:38
  • Not numpy specific, but you should watch [this video](https://www.youtube.com/watch?v=_AEJHKGk9ns) for the basics on assignment. Most important aspect with respect to your question: assignment never copies data. – timgeb Feb 18 '22 at 14:39
  • `arr2[arr1] = np.array([1,1])` mutates `arr2`. `x[0]=1` mutates `x`.. Lists contain references, arrays don't, so the mutation details are different. – hpaulj Feb 18 '22 at 16:18
  • @luk2302, I don't see anything in this question about sliced assignment of a list. The `arr2` assignment that puzzles the OP is 'advanced indexing' assignment of a `numpy` array. That `obj[...] = ...` is a mutation operation is a general Python syntax, but the details depend on the class of `obj` (list and arrays are different). – hpaulj Feb 18 '22 at 16:53
  • Max, your question isn't clear. The two mutating assignments are similar at the Python syntax level, but different at the class implementation level. That `y=x` bit is just a distraction. – hpaulj Feb 18 '22 at 16:55
  • `x[0]` is implemented as `x.__getitem__(0)`. `x[0]=1` is `x.__setitem__(0,1)`. `__getitem__` and `__setitem__` are class specific methods. – hpaulj Feb 18 '22 at 17:11
  • For a a list `x[0]=1` does change the object referenced by `x[0]`. But arrays don't store references (unless object dtype), so assignment to its elements - whether with a scalar, array or slice index, changes values (in the `data-buffer`). The data model for arrays is different from lists - different at the compiled code level. – hpaulj Feb 18 '22 at 18:11
  • Oh okay, thank you - my confusion was with "=" denoting a "__setitem__" or "__getitem___" call, not "assignment" as before. – Max Kaufmann Feb 19 '22 at 14:12

0 Answers0