Introductory tutorials, case source code, learning materials, readership
Please visit: python666.cn
Hello everyone, welcome to Crossin's programming classroom!
In today’s article, I will continue to slap the face of all kinds of parallel import tutorials on the Internet.
A while ago we talked about some content about function parameter passing and variable assignment in Python: Is Python passing by reference or passing by value? Most tutorials online are wrong
Let’s briefly review the previous points:
1. Variables in Python are not " containers " containing objects, but " labels " attached to objects .
2. Parameter passing is equivalent to an assignment : one more label is pasted.
3. As for whether the modification of the parameter inside the function will affect the value of the external variable, it depends on how you modify it: if it is reassignment, it will not, if it is modifying the content of the object itself, it will.
Speaking of this, there is a concept that is often mentioned:
mutable objects and immutable objects
In Python,
mutable objects include list, dict, set, custom types , etc.;
immutable objects include int, float, bool, str, tuple , etc.
Immutable objects do not allow modification of their contents. Many tutorials say this: If we assign a value to an immutable object, we actually generate a new object, and then let the variable point to this object. Even if the object is as simple as the numbers 0 and 1:
a = 0
print('a', id(a))
a = 1
print('a', id(a))
output:
a 4463151440
a 4463151472
This sentence is true. But this statement is actually very misleading! Don't I generate a new object if I assign a value to a mutable object?
a = [0]
print('a', id(a))
a = [1]
print('a', id(a))
output:
a 140286304509768
a 140286304509832
Isn't this also changed! Whenever a variable is assigned a new value, a new object is generated. We will talk about this later.
Because objects are immutable, Python uses some common objects for efficiency:
a = 1
print('a', id(a))
b = 1
print('b', id(b))
print(a == b)
print(a is b)
c = 'hello world'
print('c', id(c))
d = 'hello world'
print('d', id(d))
print(c == d)
print(c is d)
output:
a 4423761776
b 4423761776
True
True
c 4430180912
d 4430180912
True
True
is
This operator is mentioned here by the way . ==
The difference between it and is that ==
it only judges whether the "value" is equal, is
while judges whether it is the same object, that is, the addresses are consistent. for example:
a = 2
b = 2.0
print(a == b)
print(a is b)
output:
True
False
Insert a sentence here, to judge whether a list contains the in operator of a certain element, do you think it judges == or is ? Guess what this output is:
print(1.0 in [1, 2, 3])
The difference from immutable objects is that in addition to being assigned a value, mutable objects can also modify their own content, such as:
m = [1, 2, 3]
print('m', m, id(m))
m[1] = 4
print('m', m, id(m))
m.append(5)
print('m', m, id(m))
output:
m [1, 2, 3] 4536815752
m [1, 4, 3] 4536815752
m [1, 4, 3, 5] 4536815752
It can be seen that although the value of m has changed, the address has not changed, and it is still the original m.
I also said last time that many tutorials use mutable and immutable to talk about assignment and parameter passing. I think these authors didn’t understand it themselves. Because they use assignment when citing immutable objects, while citing mutable objects use methods such as list index and apeend, which are completely different things. As I wrote earlier, if everyone assigns a value, the effect is the same whether it is variable or not, and a new object will be generated without affecting the value of the original variable.
So if you understand the assignment principle of Python, you will understand that it has nothing to do with whether it is variable or not. And mutable objects differ from immutable objects themselves only in that one can modify the value of the variable while the other does not.
There is another difference in function between the two: the immutable object can be used as the key of the dictionary dict , but the mutable object cannot. For example, a list cannot be used as a key of a dictionary, but a tuple can.
In addition, if you understand the difference between variable and immutable, the effect of some methods will be easier to understand:
s = 'abc'
s2 = s.replace('b', 'd')
print('s', s)
print('s2', s2)
m = [1, 2, 3]
m2 = m.reverse()
print('m', m)
print('m2', m2)
output:
s abc
s2 adc
m [3, 2, 1]
m2 None
Because str
is an immutable object, its methods such as replace
, strip
, upper
cannot modify the original object, and only return a new object , which must be reassigned. It list
is a mutable object, and its methods such as reverse
, sort
, append
and are all directly modified on the original object , and have no return value.
However, there is a special case to be aware of:
m = [1, 2, 3]
print('m', m, id(m))
m += [4]
print('m', m, id(m))
m = m + [5]
print('m', m, id(m))
output
m [1, 2, 3] 4494164104
m [1, 2, 3, 4] 4494164104
m [1, 2, 3, 4, 5] 4494181128
m = m +
and m +=
Although it is the same result, the object pointed to by m has changed. The reason is that the former is an assignment operation, while the latter is actually __iadd__
a method .
If we just need to generate a copy of the list object, we can pass [:]
:
m = [1, 2, 3]
print('m', m, id(m))
n = m[:]
print('n', n, id(n))
n[1] = 4
print('m', m)
print('n', n)
In this way, the modification of n will no longer affect m, because they are not the same object.
So what if this is the case:
m = [1, 2, [3]]
n = m[:]
n[1] = 4
n[2][0] = 5
print(m)
Guess what is the result of m? Welcome to say your answer in the comment area.
Then go to Python and execute it to see if the output is as expected. Think about why? This involves the concept of shallow copy and deep copy, we will talk about it next time.
Thank you for retweeting and liking ~
_Previous article recommendation_
What do I use to write Python?
If you need to know about paid quality courses and teaching Q&A services
Please reply in Crossin's programming classroom : 666