No matter what kind of object we were iterating over or how that object was implemented, it would be almost impossible for x = 2*x
to do anything useful to that object. x = 2*x
is an assignment to the variable x
; even if the previous contents of the x
variable were obtained by iterating over some object, a new assignment to x
would not affect the object we're iterating over.
In this specific case, iterating over a NumPy array with np.nditer(a, op_flags = ['readwrite'])
, each iteration of the loop sets x
to a zero-dimensional array that's a writeable view of a cell of a
. x[...] = 2*x
writes to the contents of the zero-dimensional array, rather than rebinding the x
variable. Since the array is a view of a cell of a
, this assignment writes to the corresponding cell of a
.
This is very similar to the difference between l = []
and l[:] = []
with ordinary lists, where l[:] = []
will clear an existing list and l = []
will replace the list with a new, empty list without modifying the original. Lists don't support views or zero-dimensional lists, though.