Is += a Shortcut for x = x + y?

Is the += command a shortcut to saying: annual_rainfall = annual_rainfall + november_rainfall?

10 Likes

Hi @oadin,

That’s correct. The += operator is only used because it’s more convenient to type out.

6 Likes

Values can implement += differently if they wish. If the value is mutable then the in-place version likely modifies the value rather than creating a new one.

a = b = []
b += range(3)
print(a)  # [0, 1, 2]
a = b = []
b = b + range(3)
print(a)  # []
6 Likes
>>> b = b + range(3)
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    b = b + range(3)
TypeError: can only concatenate list (not "range") to list
>>> b = b + list(range(3))
>>> b
[0, 1, 2, 0, 1, 2]
>>> a
[0, 1, 2]
>>> 
1 Like

Right. That’s another difference. list’s + doesn’t iterate, but += does

I do wonder why + doesn’t also iterate over the other value

Sorry, I did precurse the above these two lines…

>>> a = b = []
>>> b += range(3)

Which lends itself to your quesiton of the difference. Hmmm?

+ is plus, and concatenate, and nothing more. += (as with any assignment operator) is a method. That enlarges the playing field (my take on it).

1 Like

+= is in-place add, it stands to reason it does the same thing as + aside from being in-place

I think it (list’s +=) might have been implemented using list.extend’s code and therefore got an extra feature which then couldn’t be removed.
But that’s purely a guess, and I don’t really need a reason

Take for example set’s &=
It doesn’t accept an iterable, neither does |= or ^=
And not str’s +=

list’s += is the odd one out

1 Like

No, in Python everything is an object, in case of operators what happens under the hood is that the interpreter is using magic methods.

x = x + y

equals to calling

x = x.__add__(y)
x += y

equals to

x = x.__iadd__(y)

You can check this pseudo integer implementation to see the difference

class MyInteger:
    def __init__(self, value=0):
        self.value = value

    def __add__(self, other):
        return MyInteger(self.value + other)

    def __iadd__(self, other):
        return "Not exactly the same."

    def __repr__(self):
        return f"{self.value}"


x = MyInteger(10)
print(x)
x = x + 10
print(x)
x += 10
print(x)

You would have to check documentation for how they’re implemented for built-in types, but my guess is that they work differently for modifiable types, x = x + y probably creates new objects while x += y modifies existing ones.

i don’t understand this.please help me.

1 Like

What the code demonstrates is that at first a and b reference the same list object. Changes to b will reflect in a since they point to the same thing.

The second example reassigns b with a new object, b + [0,1,2] (that’s what range(3) gives us). It no longer points to the same object as a and is now independent of it. They are two different pointers referencing two different objects.

1 Like