Whether the expressions I + = x and I = I + x in Python are equivalent.
Preface
Recently, I saw a question that seems very simple. In fact, it has a deep meaning. Is the Python expression I + = x equivalent to I + x? If your answer is yes, congratulations, 50% is correct. Why is it half the correct answer? According to our general understanding, they are equivalent. During integer operations, there are no similarities and differences between the two, but is the same for list operations?
Let's take a 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 l2 values in code 1 and Code 2 are the same, but the l1 values are different, which means that I + = x is not equivalent to I + x, under what circumstances is it equivalent, and under what circumstances is it not equivalent?
Before figuring out this problem, you should first understand two concepts: mutable objects and immutable objects.
In Python, any object has three common attributes: Unique Identifier, type, and value.
Unique Identifier:Identifies the uniqueness of an object in the memory. It will not be changed after the object is created. The function id () can be used to view the unique identifier of the object.
Type:Determines the operations supported by the object. operations supported by different types of objects are different. For example, the List can have the length attribute, but the integer does not. Once the object type is determined, it will not be changed. The function type () can return the object type information.
The object value is different from the unique identifier. Not all object values are static. Some object values can be changed through some operations, objects whose values can be changed are called mutable objects, and objects whose values cannot be changed are called immutable objects)
Immutable)
For an immutable object, the value is always the value at the beginning of creation. Any operation on this object will lead to the creation of a new object.
>>> a = 1>>> id(a)32574568>>> a += 1>>> id(a)32574544
The integer "1" is an unchangeable object. When initially assigned a value, a points to the integer object 1, but after performing the + = operation on variable, a points to another integer object 2, but object 1 remains unchanged, and variable a has pointed to a new object 2. Common immutable objects include int, tuple, set, and str.
Mutable)
The value of a variable object can be dynamically changed through some operations. For example, a list object can be added 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 of the variables, it also affects another 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 the append operation is executed, the memory address of the object will not change. x and y still point to the same original object, but their values have changed.
After understanding the mutable object and the immutable object, return to the problem itself. What is the difference between ++ and ++?
+ = The operation first tries to call the _ iadd _ method of the object. If this method is not available, try to call the _ add _ method.First, let's take a look at the differences between the two methods.
Differences between _ add _ and _ iadd _
- The _ add _ method receives two parameters and Returns their sum. The values of the two parameters remain unchanged.
- The _ iadd _ method also receives two parameters, but it belongs to the in-place operation, that is, it will change the value of the first parameter, because this requires the object to be variable, therefore, there is no _ iadd _ Method for immutable objects.
>>> hasattr(int, '__iadd__')False>>> hasattr(list, '__iadd__')True
Obviously, the integer object does not have _ iadd _, while the list object provides the _ iadd _ method.
>>> L2 + = [3] # code 1: Use _ iadd __, and modify the l2 value in situ.
In code 1, The + = operation calls the _ iadd _ method, which modifies the value of the object to which l2 points.
>>> L2 = l2 + [3] # Code 2: Call _ add __. a new list is created and assigned to l2.
The + operation in Code 2 calls the _ add _ method. This method returns a new object, the original object remains unchanged, and l1 still points to the original object, l2 has pointed to a new object.
The above is the difference between the expression I + = x and I = I + x. Therefore, when you perform the + = operation on the list, there will be a potential bug, because l1 will change due to l2 changes, just as the function parameters should not use variable objects as keyword parameters.
Summary
The above is all about this article. I hope this article will help you in your study or work. If you have any questions, please leave a message.