3 ms·
> To reduce memory usage, you can use in-place operations like += btw, I think it's a design flaw in python that `a += b` is not always equivalent to `a = a +
by perfunctory 7y ago
> To reduce memory usage, you can use in-place operations like +=
btw, I think it's a design flaw in python that `a += b` is not always equivalent to `a = a + b`.
- notduncansmith 7y agoAs someone who has never used Python seriously I have to ask... why not?
- falkaer 7y agoPython defines += as the __iadd__ method which is sometimes mutating, i.e. if the object being assigned to is mutable or not.
- perfunctory 7y agoBecause 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.
- im3w1l 7y agoThey aren't equivalent in C++ either.
- perfunctory 7y agoMy 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.
- zabzonk 7y ago> 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.
- cultureswitch 7y agoIt's not equivalent but honestly this gotcha with lists will only show up in bad code and interview quizzes (i.e. bad code).
- masklinn 7y agoAs 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).
- Sohcahtoa82 7y agoWait...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.
- masklinn 7y agoYou got it, that’s why it’s so odd.
- ben509 7y agoIt'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.__iadd__ https://docs.python.org/3/reference/datamodel.html#object.__...