3

Consider the multiple assignment x[0],y = y,x[0]. Applied to each of the four below cases, this gives four different results.

  • Case 1:

    x = [[1,2], [3,4]]
    y = [5,6]
    

    gives

    x = [[5,6], [3,4]]
    y = [1,2]
    
  • Case 2:

    x = np.array([[1,2], [3,4]])
    y = [5,6]
    

    gives

    x = array([[5,6], [3,4]])
    y = array([5,6])
    
  • Case 3:

    x = [[1,2], [3,4]]
    y = np.array([5,6])
    

    gives

    x = [array([5,6]), [3,4]]
    y = [1,2]
    
  • Case 4:

    x = np.array([[1,2], [3,4]])
    y = np.array([5,6])
    

    gives

    x = array([[5,6], [3,4]])
    y = array([5,6])
    

It appears that the multiple assignment of lists is smarter (going through a temporary variable automatically) than the multiple assignment of Numpy arrays.

Thoughts?

EDIT: It is not smarter afterall...

Gioker
  • 649
  • 5
  • 14
  • "It appears that the multiple assignment of lists is smarter (going through a temporary variable automatically) than the multiple assignment of Numpy arrays." -- How so? When assigning into a Numpy array, it turns that into part of the Numpy array. – Scimonster Dec 15 '16 at 09:35

2 Answers2

5

The only surprising cases here should be 2 & 4:

x = np.array([[1,2], [3,4]])
y = np.array([5,6])  # or [5, 6]

giving

x = array([[5,6], [3,4]])
y = array([5,6])  # where did the 1 and 2 go?

Since the others are just swapping around data types, but keeping the same values.

What's different when using numpy is that x[0] returns a view, not a copy. So even writing out the temporary in the tuple assignment explicitly fails:

temp = x[0]
x[0] = y
y = temp

Because temp is a view that is always the same as x[0], not a copy of the value of x[0] at that point in time.

To make this work for the numpy case, you should use x[0],y = y,x[0].copy()

Eric
  • 95,302
  • 53
  • 242
  • 374
1
x[0],y = y,x[0]

equals

t = x[0]
x[0] = y
y = t

As @Scimonster pointed out,

When assigning into a Numpy array, it turns that into part of the Numpy array.

So It's normal behavior.

gzc
  • 8,180
  • 8
  • 42
  • 62
  • It is not really true that these two code blocks are equal. Not temporary variable `t` is created; internally `y` and `x[0]` are pushed on to a stack, get flipped, and then are popped back off to be assigned. The two approaches can lead to different results. – Alex Riley Dec 15 '16 at 10:31
  • @ajcr: Apart from the name `t` being clobbered, can you construct a case where the results do differ? – Eric Dec 15 '16 at 10:57
  • @Eric: I think I was mis-remembering something like [this question](http://stackoverflow.com/questions/31566500/python-setting-two-variable-values-separated-by-a-comma-in-python/31566736#31566736) that I came across a while ago (which I see now doesn't involve a temporary variable). I think it should be possible to construct strange examples that mutate variables inplace during the assignment (so leaving a temporary variable unchanged) but until I can come up with something compelling, I'll retract my previous comment. – Alex Riley Dec 15 '16 at 11:55