Home > Article > Backend Development > Detailed explanation of whether the expressions i += x and i = i + x in Python are equivalent
This article mainly introduces the relevant information about whether the expressions i += x and i = i + x in Python are equivalent. The article introduces it in detail through the example code. I believe it has certain reference value for everyone. Friends who need it can come and take a look below.
Preface
I recently saw a question that seemed very simple, but in fact it had a deep meaning. The question was the Python expressions i += x and i = Is i + x equivalent? If your answer is yes, then congratulations, you are 50% correct. Why do you say it is only half correct? According to our general understanding, they are equivalent. There are no similarities or differences between the two when it comes to integer operations, but is it the same for list operations?
First look at the following two pieces of code:
Code 1
>>> l1 = range(3) >>> l2 = l1 >>> l2 += [3] >>> l1 [0, 1, 2, 3] >>> l2 [0, 1, 2, 3]
Code 2
>>> l1 = range(3) >>> l2 = l1 >>> l2 = l2 + [3] >>> l1 [0, 1, 2] >>> l2 [0, 1, 2, 3]
The values of l2 in code 1 and code 2 are the same, but the values of l1 are different, indicating that i += x and i = i + x They are not equivalent, so under what circumstances are they equivalent and under what circumstances are they not?
Before clarifying this issue, you must first understand two concepts: mutable objects and immutable objects.
There are three common attributes that any object in Python has: unique identifier, type, and value.
Unique identification: is used to identify the uniqueness of an object in memory. It will not change after the object is created. The function id() can view the object. The unique identifier
type: determines which operations the object supports. Different types of objects support different operations. For example, a list can have a length attribute, and Integers don't. Similarly, once the type of an object is determined, it will not change. The function type() can return the type information of the object.
The value of an object is different from a unique identifier. Not all object values are immutable. The values of some objects can be changed through certain operations. Objects whose values can change are called mutable objects. (mutable), objects whose values cannot be changed are called immutable objects (immutable)
Immutable objects (immutable)
For immutable objects, the value is always The value when it was first created. Any operation on the object will result in the creation of a new object.
>>> a = 1 >>> id(a) 32574568 >>> a += 1 >>> id(a) 32574544
The integer "1" is an immutable object. When initially assigned, a points to the integer object 1, but the += operation is performed on the variable a. Finally, a points to another integer object 2, but object 1 is still there without any change, and variable a already points to a new object 2. Common immutable objects include: int, tuple, set, str.
Mutable object (mutable)
The value of a mutable object can be dynamically changed through certain operations. For example, a list object can continuously add elements to the list through the append method, and the value of the list is constantly changing. When a variable object is assigned to two variables, they share the same instance object and point to the same memory. Address, when operating on any one of the variables, it will also affect the other variable.
>>> x = range(3) >>> y = x >>> id(x) 139726103041232 >>> id(y) 139726103041232 >>> x.append(3) >>> x [0, 1, 2, 3] >>> y [0, 1, 2, 3] >>> id(x) 139726103041232 >>> id(y) 139726103041232
After executing the append operation, the memory address of the object will not change, and x and y still point to the original same address. An object is just that its value has changed.
After understanding mutable objects and immutable objects, back to the question itself, what is the difference between += and +?
+= The operation will first try to call the __iadd__ method of the object. If there is no such method, then try to call the __add__ method . Let’s take a look at this first. What is the difference between the two methods
The difference between __add__ and __iadd__
__add__ method receives two parameters and returns their sum. The values of the parameters will not change.
__iadd__ method also receives two parameters, but it is an in-place operation, which means that it will change the value of the first parameter, because this requires the object to be variable. So there is no __iadd__ method for immutable objects.
>>> hasattr(int, '__iadd__') False >>> hasattr(list, '__iadd__') True
Obviously, the integer object does not have __iadd__, but the list object provides the __iadd__ method.
>>> l2 += [3] # 代码1:使用__iadd__,l2的值原地修改
代码1中的 += 操作调用的是__iadd__方法,他会原地修改l2指向的那个对象本身的值
>>> l2 = l2 + [3] # 代码2:调用 __add__,创建了一个新的列表,赋值给了l2
而代码2中的 + 操作调用的是 __add__ 方法,该方法会返回一个新的对象,原来的对象保持不变,l1还是指向原来的对象,而l2已经指向一个新的对象。
以上就是表达式 i += x 与 i = i + x 的区别。因此对于列表进行 += 操作时,会存在潜在的bug,因为l1会因为l2的变化而发生改变,就像函数的参数不宜使用可变对象作为关键字参数一样。
更多详解Python中表达式i += x与i = i + x是否等价相关文章请关注PHP中文网!