1

I am using Jupyter Notebook for Python and also using Numpy Lib. Here is what i have tried

import numpy as np
arr = np.arange(10, 21)
print(arr)
slice_arr = arr[:5]= 6
print(slice_arr)
print(arr)

Output is :

[10 11 12 13 14 15 16 17 18 19]
6
[ 6  6  6  6  6 15 16 17 18 19]

But I thought slice_arr would be [ 6 6 6 6 6] as i am getting first 5 element from arr and assigning 6 to all 5 elements and then assigning to slice_arr

How this statements would executed and How slice_arr value is 6?

Does 6 is assigned separately to arr[:5] and slice_arr?

If the assignment if from right to left then slice_arr should be [ 6 6 6 6 6]

Thanks in advance

Abu Yousuf
  • 5,729
  • 3
  • 31
  • 50

2 Answers2

3

https://docs.python.org/3/reference/simple_stmts.html#assignment-statements

An assignment statement evaluates the expression list (remember that this can be a single expression or a comma-separated list, the latter yielding a tuple) and assigns the single resulting object to each of the target lists, from left to right.

To get what you want, maybe do this:

slice_arr = arr[:5] = np.zeros([5])+6

Gavin Haynes
  • 1,721
  • 11
  • 21
2

Multiple assignments like this are not common, and not encouraged (without good reason):

slice_arr = arr[:5]= 6

Assigning an immutable object like a number to several variables is fine:

In [215]: x = y = 10

Assigning a mutable object like an array or list should be done with caution:

In [216]: x = y = [1,2,3]
In [217]: x[0]=12
In [218]: y
Out[218]: [12, 2, 3]

The simple interpretation of [216] is that the same list is assigned to both variables.

While I haven't seen your expression before, it makes sense to me that slice_arr would be 6, the value on the RHS.

The arr[:5] = 6 is executed as arr.__setitem(slice(None,5), 6), that is, a method call on arr.

Conceivably the interpreter could also execute slice_arr = arr.__getitem__(slice(None,5)), but it would be simpler (and less ambiguous) if it is executed slice_arr = 6. That is, assign the same thing to both objects, rather than chain the action.

Another way to look at this, is that the replication of 6 is done within arr, or as part of the process of mutating arr. It isn't replicated before the assignment. numpy operates within Python. The Python interpreter parses the code, translating it into function and method calls.


Here's a list example

In [235]: x=[1,2,3]
In [236]: y = x[1:] = [3,4,5]
In [237]: y
Out[237]: [3, 4, 5]
In [238]: x
Out[238]: [1, 3, 4, 5]

The documentation says the target assignments are done left to right. I think this illustrates that:

In [43]: alist = alist[2:] = [1,2,3]
In [44]: alist
Out[44]: [1, 2, 1, 2, 3]

alist first gets the value [1,2,3], and then a slice (the last element) is replaced by the same list.

A somewhat artificial array example of the left to right assignment:

In [45]: arr = np.arange(10)
In [46]: idx = arr[:idx] = 6
In [47]: idx
Out[47]: 6
In [48]: arr
Out[48]: array([6, 6, 6, 6, 6, 6, 6, 7, 8, 9])
In [49]: idx = arr[:idx] = 4
In [50]: arr
Out[50]: array([4, 4, 4, 4, 6, 6, 6, 7, 8, 9])

idx is assigned the value before being used in the arr[:idx] expression. This only works because the assignments are executed left to right (after the RHS has been evaluated).

From the assignment docs, the formal language expression is:

https://docs.python.org/3/reference/simple_stmts.html#assignment-statements

assignment_stmt ::= (target_list "=")+ (starred_expression | yield_expression)

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Thanks for you answer. So here the right most value `6` is assigned separately to `arr[:5]` and `slice_arr`, am i right @hpaulj ? – Abu Yousuf Dec 16 '17 at 08:10
  • @AbuYousuf, right. the `expression list` (in @Gavin's reference) is evaluated once, and the assignment to `targets` is done individually. I added an example showing that the `target` assignment occurs left to right (in your case `slice_arr` is assigned 6 first). – hpaulj Dec 16 '17 at 17:24