Python provides the operator x *= y
to multiply two objects in-place by calculating the product x * y
and assigning the result to the first operands variable name x
. You can set up the in-place multiplication behavior for your own class by overriding the magic “dunder” method __imul__(self, other)
in your class definition.
>>> x = 2 >>> x *= 3 >>> x 6
The expression x *= y
is syntactical sugar for the longer-form x = x * y
:
>>> x = 2 >>> x = x * 3 >>> x 6
Let’s explore some examples on different data types of the operands.
Integer Example
The *=
operator on integer operands stores the mathematical product of both operands in the left-hand operands’ variable name.
>>> x = 2 >>> x *= 21 >>> x 42
Float Example
If at least one of the operands is a float value, the result is also a float—float is infectious!
>>> x = 2 >>> x *= 21.0 >>> x 42.0
String Example
Can we multiply a string with an integer in-place? Of course! The result is a new string object created by concatenating the first string multiple times as specified by the second integer operand. This is called string concatenation:
>>> x = 'learn! ' >>> x *= 3 >>> x 'learn! learn! learn! '
List Example
If the first operand is a list, the result of the in-place multiplication operation overwrites an existing list:
>>> my_list = ['Alice', 'Bob'] >>> my_list *= 3 >>> my_list ['Alice', 'Bob', 'Alice', 'Bob', 'Alice', 'Bob']
The in-place multiplication operator on lists doesn’t create a new list object but works on an existing list. Changing the list in-place for one variable x
has side-effects. For instance, another variable my_list
may point to the same object in memory that is updated through the use of in-place multiplication on any other variable pointing to that same object in memory.
>>> my_list = ['Alice', 'Bob'] >>> x = my_list >>> x *= 3 >>> x ['Alice', 'Bob', 'Alice', 'Bob', 'Alice', 'Bob'] >>> my_list ['Alice', 'Bob', 'Alice', 'Bob', 'Alice', 'Bob']
Incompatible Data Type
What if two operands have an incompatible data type—unlike floats and integers? For example, if you try to multiply a list with a list in place?
>>> x = [1, 2] >>> x *= [1, 2] Traceback (most recent call last): File "<pyshell#12>", line 1, in <module> x *= [1, 2] TypeError: can't multiply sequence by non-int of type 'list'
The result of incompatible addition is a TypeError
. You can fix it by using only compatible data types for the in-place multiplication operation.
Can you use the operator on custom objects? Yes!
Python In-Place Multiplication Magic Method
To use the in-place multiplication operator *=
on custom objects, define the __imul__()
method (“dunder method”, “magic method”) that takes two arguments self
and other
, updates the first argument self
with the result of the multiplication, and returns the updated object.
In the following code, you multiply two Data
objects by combining their contents:
class Data: def __init__(self, data): self.data = data def __imul__(self, other): self.data *= other.data return self x = Data(21) y = Data(2) x *= y print(x.data) # 42
You can see that the content of the first operand is updated as a result of the in-place multiplication operation.
Python In-Place Operators
In-place assignment operators (also called compound assignment operators) perform an operation in-place on a variable provided as first operand. They overwrite the value of the first operand variable with the result of the operation when performing the operator without assignment. For example, x += 3
is the same as x = x + 3
of first calculating the result of x +3
and then assigning it to the variable x.
Operator | Name | Short Example | Equivalent Long Example |
---|---|---|---|
= | In-place Assignment | x = 3 | |
+= | In-place Addition | x += 3 | x = x + 3 |
-= | In-place Subtraction | x -= 3 | x = x - 3 |
*= | In-place Multiplication | x *= 3 | x = x * 3 |
/= | In-place Division | x /= 3 | x = x / 3 |
%= | In-place Modulo | x %= 3 | x = x % 3 |
//= | In-place Integer Division | x //= 3 | x = x // 3 |
**= | In-place Power | x **= 3 | x = x ** 3 |
&= | In-place Bitwise And | x &= 3 | x = x & 3 |
|= | In-place Bitwise Or | x |= 3 | x = x | 3 |
^= | In-place Bitwise XOR | x ^= 3 | x = x ^ 3 |
>>= | In-place Bitwise Shift Right | x >>= 3 | x = x >> 3 |
<<= | In-place Bitwise Shift Left | x <<= 5 | x = x << 5 |