-2

In python : I have 2 pieces of code behaving different when I modify values:

X = Y = Number

x = y = 2
x = 3

print(x)
print(y)

Output:
3
2

X = Y = [List]

x = y = ['a','b']
x[0] = 'd'

print(x)
print(y)

Output:
['d', 'b']
['d', 'b']

Why don't LISTS respect the original value of variable Y if X is changed?

GoldMamba
  • 21
  • 1
  • 5
  • The issue here is that your code **isn't the same**. In the second case, you are muting an object, in the first case, `x = 3` doesn't mutate any objects, it merely reassigns `x`. It works exactly the same way with `list` objects if you did `x = 'd'` in your second example – juanpa.arrivillaga Jan 11 '20 at 23:15
  • `x=3` and `x[0]='d'` are two very different operations. One assigns a new value to a variable. The other assigns a new value to an element of a list. You may need to learn more about Python lists. – hpaulj Jan 11 '20 at 23:16

1 Answers1

4

These two cases are more different than they seem, and it isn't because of the types involved.

x = 3

This changes what value x is looking at. Reassigning x using = does not change the 3. It wouldn't matter if the right hand side were a int, or a list. Whatever is on the right is put into the variable on the left.

x[0] = 'd'

This looks the same, but it's actually quite different. Instead of a simple reassignment, this is actually internally translated to

x.__setitem__(0, 'd')

Instead of being just a reassignment, this is actually a mutative operation that changes the object x is holding.

So the reason the latter acts differently is that instead of changing what object x is holding, you're altering the object itself that x is holding.

You can tell the two cases apart based on what's on the left of =. If the left is a simple variable name (x =), it's a plain reassignment. If the left side uses [] (x[0] =) or anything other kind of "accessor" syntax like a . (x.attr =), you're altering the object that x is holding.

Carcigenicate
  • 43,494
  • 9
  • 68
  • 117
  • I think everyone (especially in the question comments) is focused on the fact that `x[0] = 'd'` is the operation, but not making it clear the actually confusing part, which is that we expect `y` to stay the same. `x` and `y` are both pointing to the same list object, so changing `x` changes `y`. It's not unreasonable to expect them to be independent if you are dealing with them much further down the line (like if you had no part in the original assignment code), so the real issue is using `x = y = [list]` when it isn't explicitly to link together permanently. (right?) – Anthony Aug 29 '20 at 04:01
  • @Anthony The real issue is understanding what objects names like `x` and `y` are referencing. It isn't unreasonable to expect that they'll be different later if that's been suggested via comments or some other means that they're different. If you can view where `x` and `y` are assigned though, and you understand how `x = y = ['a','b']` works, there is no problem. Misusing chained assignments and not understanding the code you're using are the problem, not anything related to a statement like `x = y = ['a','b']` itself. – Carcigenicate Aug 29 '20 at 04:09
  • I'll admit too though that I may have misunderstood what you were commenting on. I'm quite tired. – Carcigenicate Aug 29 '20 at 04:17