1

I have just came up with an example of code:

ls = [2222, 1111]

a = ls[0]
print(a is ls[0])

a, ls[1] = ls[1], a
print(ls)

which prints:

True
[2222, 2222]

My question is, why isn't a the same object as ls[0] in the above case? The a is ls[0] check is True, therefore it must be the same as:

ls[0], ls[1] = ls[1], ls[0]

but it isn't. The latter one produces [1111, 2222]. What is this mYsTeRy?

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
Oleksandr Novik
  • 489
  • 9
  • 24

4 Answers4

3

Simple assignments have no affect on the previous value of the target.

After

ls = [2222, 1111]

a = ls[0]

both a and the first element of ls are references to the integer 2222.

The assignment

a, ls[1] = ls[1], a

is effectively the same as

t = ls[1], a  # The tuple (1111, 2222)
a = t[0]  # Set a to t[0] == 1111
ls[1] = t[1]  # Set ls[1] to t[1] == 2222

At no point have you modified the first element of ls; you've only changed what a refers to and what the second element of ls refers to. You can see that a is now refers to 1111, since that's what the value of ls[1] was before ls[1] was modified.

>>> print(a)
1111
chepner
  • 497,756
  • 71
  • 530
  • 681
1

You are not setting ls[0]!

Fixing it:

ls = [2222, 1111]

# Assigns ls[0] to a, but not changes ls[0]!
a = ls[0]
print(a is ls[0])

# Assigns ls[1] to a and a to ls[1]. At this point ls[1] is a!
a, ls[1] = ls[1], a
print(ls)

# Now ls[0] is assigned!
ls[0] = a
print(ls)

Outputs:

True
[2222, 2222]
[1111, 2222]

BTW: You can do the reverse listing with:

ls = [2222, 1111]
print(ls[::-1])

Outputs:

[1111, 2222]
pinxau1000
  • 301
  • 1
  • 11
  • I still don't understand why it doesn't set `l[0]`. My `a is ls[0]` proved that they are the same object. – Oleksandr Novik Jan 10 '22 at 18:02
  • @AleksandrNovik `a` is just a name. Not an object. The fact that both the name `a` and `l[0]` refer to the same object doesn't mean that changing which object one name points to effects the other. – Axe319 Jan 10 '22 at 18:04
  • 2
    They are two *references* to the same object. Subsequent assignments to the name `a` have nothing to do with any other references to `a`'s old value. – chepner Jan 10 '22 at 18:05
  • @chepner is right. – pinxau1000 Jan 10 '22 at 18:07
0

Taken literally, neither a nor ls[1] are objects: They are an identifier and subscription, respectively. While they evaluate to objects when used in an expression, that does not make them identical to these objects – and the identity of "their" objects does not extend to them, either.

  • The expression a is ls[0] means "evaluate a and ls[0] and compare the result for identity". It does not check whether the identifier a is identical to the subscription ls[0].

Notably, when used in an assignment statement, both a and ls[1] do not represent "an expression to look up an object" but rather "a target to assign an object to". The features of the former do not impact the latter.


The statement a, ls[1] = ls[1], a uses both a and ls[1] as both expressions and targets:

  • The right hand side is an expression. It represents "a tuple of the results of evaluating ls[1] and a".

  • The left hand side is an assignment. It represents "assign to the identifier a and the subscription ls[1]".

Assignment to an identifier always is immediate: it does not matter what value the identifier previously referred to. Specifically, it does not matter that a previously referred to an object that was also referred to by ls[0], and it will not matter that its new referent was also referred to by ls[1].


To understand why this distinction is important, consider the case that an identifier "is identical to" a literal:

>>> # integers < 256 are interned
>>> a = 12
>>> # identifier "is identical to" literal
>>> a is 12
True

If identity in expressions would equate to identity in assignments, then setting a = 13 would now reassign both a and 12 to have the value 13.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
-2

This code would not work as in this case you have a reference to the object at ls[0] and not a reference to the memory position of ls[0].

Jorge Machado
  • 202
  • 1
  • 3