News for hackers. Stuff that matters.
Re:Copying data is wasteful, mutating data is dangerous by notduncansmith on Thursday January 09, 2020 @02:16PM (#22004444)
As someone who has never used Python seriously I have to ask... why not?
Re:Copying data is wasteful, mutating data is dangerous by masklinn on Thursday January 09, 2020 @03:08PM (#22005078)
As an optimisation, you can override += separately from +. A pretty well known oddity related to this is:

    >>> a = ([0],) # a tuple (immutable) containing a list (mutable)
    >>> a[0] = a[0] + [1]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'tuple' object does not support item assignment
    >>> a
    ([0],)
    >>> a[0] += [1]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'tuple' object does not support item assignment
    >>> a
    ([0, 1],)
Though to be fair, technically nothing prevents "+" from mutating either operator (it'd just get you tarred and feathered).
Re:Copying data is wasteful, mutating data is dangerous by Sohcahtoa82 on Thursday January 09, 2020 @03:54PM (#22005619)
Wait...did it throw an exception, yet still add the item to the list?

EDIT: Tried it myself. Sure enough, it throws the exception, but still adds the item. This seems like a bug.

EDIT Part 2: I understand now. `a[0] += [1]` is internally translated to `a[0] = a[0].__iadd__([1])`. The right-hand side is interpreted, mutating a[0] in-place as expected. But then the re-assignment happens, which throws the exception since you're trying to re-assign a value in a tuple, which is immutable.

Re:Copying data is wasteful, mutating data is dangerous by masklinn on Friday January 10, 2020 @03:24AM (#22009365)
You got it, that’s why it’s so odd.
Re:Copying data is wasteful, mutating data is dangerous by ben509 on Friday January 10, 2020 @01:40AM (#22008834)
It's because of Python's distinction (enforced mainly by convention) between references and value types.

If you are using a value type, `__iadd__`[1] can return a new value. So:

   x = 5
   y = x
   x += 3
   y is not x and y == 5
But if you're using a reference type, it is allowed to mutate the reference and return the original reference.

   x = [1, 2]
   y = x
   x += [3, 4]
   y is x and y == [1, 2, 3, 4]
[1]: https://docs.python.org/3/reference/datamodel.html#object.__...
Re:Copying data is wasteful, mutating data is dangerous by falkaer on Thursday January 09, 2020 @02:32PM (#22004659)
Python defines += as the __iadd__ method which is sometimes mutating, i.e. if the object being assigned to is mutable or not.
Re:Copying data is wasteful, mutating data is dangerous by perfunctory on Thursday January 09, 2020 @02:33PM (#22004666)
Because I once learned that `a += b` is just a shortcut for `a = a + b`, just a syntax sugar. Now I have to constantly remind myself that it's not the case in python.

edit: I might have misunderstood your question. If you meant "why it's not equivalent" please see the falkaer's answer.

Re:Copying data is wasteful, mutating data is dangerous by cultureswitch on Friday January 10, 2020 @08:22AM (#22010730)
It's not equivalent but honestly this gotcha with lists will only show up in bad code and interview quizzes (i.e. bad code).
Re:Copying data is wasteful, mutating data is dangerous by im3w1l on Thursday January 09, 2020 @04:33PM (#22006056)
They aren't equivalent in C++ either.
Re:Copying data is wasteful, mutating data is dangerous by perfunctory on Thursday January 09, 2020 @04:40PM (#22006154)
My C++ is a bit rusty. Does it manifest itself in the standard library as well? The problem with python (in my view) is that this behaviour is implemented in the standard library and therefor propagates to the 3rd-party libraries by convention.
Re:Copying data is wasteful, mutating data is dangerous by zabzonk on Thursday January 09, 2020 @06:02PM (#22006820)
> Does it manifest itself in the standard library as well?

Yes. For example for std::string `a = a + b;` will (at least notionally) create a temporary string and then use the assignment operator. `a += b;` will not do this.