I need to know what += does in Python. It's that simple. I also would appreciate links to definitions of other shorthand tools in Python.
14 Answers
In Python, += is sugar coating for the __iadd__ special method, or __add__ or __radd__ if __iadd__ isn't present. The __iadd__ method of a class can do anything it wants. The list object implements it and uses it to iterate over an iterable object appending each element to itself in the same way that the list's extend method does.
Here's a simple custom class that implements the __iadd__ special method. You initialize the object with an int, then can use the += operator to add a number. I've added a print statement in __iadd__ to show that it gets called. Also, __iadd__ is expected to return an object, so I returned the addition of itself plus the other number which makes sense in this case.
>>> class Adder(object):
def __init__(self, num=0):
self.num = num
def __iadd__(self, other):
print 'in __iadd__', other
self.num = self.num + other
return self.num
>>> a = Adder(2)
>>> a += 3
in __iadd__ 3
>>> a
5
Hope this helps.
x += 5 is not exactly the same as saying x = x + 5 in Python.
Note here:
In [1]: x = [2, 3, 4]
In [2]: y = x
In [3]: x += 7, 8, 9
In [4]: x
Out[4]: [2, 3, 4, 7, 8, 9]
In [5]: y
Out[5]: [2, 3, 4, 7, 8, 9]
In [6]: x += [44, 55]
In [7]: x
Out[7]: [2, 3, 4, 7, 8, 9, 44, 55]
In [8]: y
Out[8]: [2, 3, 4, 7, 8, 9, 44, 55]
In [9]: x = x + [33, 22]
In [10]: x
Out[10]: [2, 3, 4, 7, 8, 9, 44, 55, 33, 22]
In [11]: y
Out[11]: [2, 3, 4, 7, 8, 9, 44, 55]
See for reference: Why does += behave unexpectedly on lists?
+= adds a number to a variable, changing the variable itself in the process (whereas + would not). Similar to this, there are the following that also modifies the variable:
-=, subtracts a value from variable, setting the variable to the result*=, multiplies the variable and a value, making the outcome the variable/=, divides the variable by the value, making the outcome the variable%=, performs modulus on the variable, with the variable then being set to the result of it
There may be others. I am not a Python programmer.
It is not mere a syntactic sugar. Try this:
x = [] # empty list
x += "something" # iterates over the string and appends to list
print(x) # ['s', 'o', 'm', 'e', 't', 'h', 'i', 'n', 'g']
versus
x = [] # empty list
x = x + "something" # TypeError: can only concatenate list (not "str") to list
The += operator invokes the __iadd__() list method, while + one invokes the __add__() one. They do different things with lists.
It adds the right operand to the left. x += 2 means x = x + 2
It can also add elements to a list -- see this SO thread.
Notionally a += b "adds" b to a storing the result in a. This simplistic description would describe the += operator in many languages.
However the simplistic description raises a couple of questions.
- What exactly do we mean by "adding"?
- What exactly do we mean by "storing the result in a"? python variables don't store values directly they store references to objects.
In python the answers to both of these questions depend on the data type of a.
So what exactly does "adding" mean?
- For numbers it means numeric addition.
- For lists, tuples, strings etc it means concatenation.
Note that for lists += is more flexible than +, the + operator on a list requires another list, but the += operator will accept any iterable.
So what does "storing the value in a" mean?
If the object is mutable then it is encouraged (but not required) to perform the modification in-place. So a points to the same object it did before but that object now has different content.
If the object is immutable then it obviously can't perform the modification in-place. Some mutable objects may also not have an implementation of an in-place "add" operation . In this case the variable "a" will be updated to point to a new object containing the result of an addition operation.
Technically this is implemented by looking for __IADD__ first, if that is not implemented then __ADD__ is tried and finally __RADD__.
Care is required when using += in python on variables where we are not certain of the exact type and in particular where we are not certain if the type is mutable or not. For example consider the following code.
def dostuff(a):
b = a
a += (3,4)
print(repr(a)+' '+repr(b))
dostuff((1,2))
dostuff([1,2])
When we invoke dostuff with a tuple then the tuple is copied as part of the += operation and so b is unaffected. However when we invoke it with a list the list is modified in place, so both a and b are affected.
In python 3, similar behaviour is observed with the "bytes" and "bytearray" types.
Finally note that reassignment happens even if the object is not replaced. This doesn't matter much if the left hand side is simply a variable but it can cause confusing behaviour when you have an immutable collection referring to mutable collections for example:
a = ([1,2],[3,4])
a[0] += [5]
In this case [5] will successfully be added to the list referred to by a[0] but then afterwards an exception will be raised when the code tries and fails to reassign a[0].
Note x += y is not the same as x = x + y in some situations where an additional operator is included because of the operator precedence combined with the fact that the right hand side is always evaluated first, e.g.
>>> x = 2
>>> x += 2 and 1
>>> x
3
>>> x = 2
>>> x = x + 2 and 1
>>> x
1
Note the first case expand to:
>>> x = 2
>>> x = x + (2 and 1)
>>> x
3
You are more likely to encounter this in the 'real world' with other operators, e.g.
x *= 2 + 1 == x = x * (2 + 1) != x = x * 2 + 1
According to the documentation
x += yis equivalent tox = operator.iadd(x, y). Another way to put it is to say thatz = operator.iadd(x, y)is equivalent to the compound statementz = x; z += y.
So x += 3 is the same as x = x + 3.
x = 2
x += 3
print(x)
will output 5.
Notice that there's also
object.__iadd__- ephemient