Detailed explanation of mutable objects and immutable objects in Python

零下一度
Release: 2017-06-30 14:30:40
Original
1873 people have browsed it

Mutable objects and immutable objects in Python

What is a mutable/immutable object

  • Immutable object, the object pointed to The value in memory cannot be changed. When a variable is changed, since the value it refers to cannot be changed, it is equivalent to copying the original value and then changing it. This will open up a new address, and the variable will point to this new address.

  • # Mutable object, the value in the memory pointed to by the object can be changed. After the variable (reference to be precise) is changed, the value it refers to is actually changed directly. No copying behavior occurs, and no new outgoing address is opened. In layman's terms, it is changed in place. .

In Python, numeric types (int and float), string str, and tuple tuple are all immutable types . Lists, dictionaries, and sets are variable types.

It’s more intuitive to look at the code. Let’s first look at the immutable objects

Examples of immutable objects

First explain one pointis is to determine whether the ids of two objects are the same, and= = The judgment is whether the content is the same.

a = 2b = 2c = a + 0 c += 0print(id(a), id(b), id(2))  # id都相同print(c is b) #True
Copy after login

Look at the string

astr = 'good'bstr = 'good'cstr = astr + ''print(cstr is bstr) # Trueprint(id(astr), id(bstr), id('good'))  # 三个id相同
Copy after login

The result is the same as the numerical type. If the following situation occurs, the variable is no longer good

astr = 'good'print(id(astr))
astr += 'aa'print(id(astr)) # id和上面的不一样
Copy after login

after modification. Since it is an immutable object, the value of the memory corresponding to the variable is not allowed to be changed. . When a variable is to be changed, the original value is actually copied and then changed, a new address is opened, and astr points to this new address (so the id of the previous and the previous astr is different). The value corresponding to the original astr is different because If another object points to it, it will be garbage collected. This is the same for int and float types.

Look at the tuple

add = (1, 2, 3)
aee = (1, 2, 3)print(id(add), id(aee), id((1, 2, 3)))  # id各不相同aee = (1, 2, 3)print(id(aee))
aee += () # 加空元组print(id(aee))  # id变了!print(aee)  #(1 ,2,3)
Copy after login

Although it looks like they are all (1,2,3) it should be consistent with the above. Is this a mutable object? Look again

add = (1, 2, 3)
aee = add 
print(id(aee), id(add)) # 这两个id一样aee += (4, 5, 6)print(id(aee)) # aee的id变了!print(add) # add还是(1, 2, 3)没有变
Copy after login

is consistent with the numeric type and the str type. If it is a mutable object add = aee, it is certain that they point to the same address (same id). But it is not different references to the same object, because if so, changes in aee will cause changes in add, which is not the case in tuple. So tuple is an immutable object, but it is slightly different from str and numeric types. The immutability of tuples usually means that the values ​​stored in them cannot be changed (In some special cases, such as a list stored in a tuple, the elements in the list can be changed. But in fact, the tuple has not been changed).

For str, int, floatAs long as they have the same type and the same value, then their ids will be the same. (Why do you say they have the same type?)

a = 2.0b = 2print(a is b)  # False, 一个int一个float,类型都不同
Copy after login

2 and 2.0 are not at the same address.

Examples of variable objects

lis = [1, 2, 3]
lis2 = [1, 2, 3]# 虽然它们的内容一样,但是它们指向的是不同的内存地址print(lis is lis2)print(id(lis), id(lis2), id([1, 2, 3]))  # 三个id都不同
Copy after login

Look at the assignment

alist = [1, 2, 3]# alist实际上是对对象的引用,blist = alist即引用的传递,现在两个引用都指向了同一个对象(地址)blist = alistprint(id(alist), id(blist))  # id一样# 所以其中一个变化,会影响到另外一个blist.append(4)print(alist)  # 改变blist, alist也变成了[1 ,2 ,3 4]print(id(alist), id(blist))  # id一样,和上面值没有改变时候的id也一样
Copy after login

blist = alistThis sentence. alist is actually a reference to the object, blist = alist is the transfer of reference, and now both references point to the same object (address). So changes in one will affect the other.

Look at the set

abb = {1, 2, 3}
acc = abbprint(id(abb), id(acc))
acc.add(4)print(abb)  # {1, 2, 3, 4} print(id(abb), id(acc)) # 相等
Copy after login

which is consistent with the example in the list above.

The variable object refers to a variable object that can be modified, so there is no need to make a copy and then change it. It can be changed directly in place, so no new memory will be opened, and the id remains unchanged before and after the change.

Of course this is not the case for immutable objects. You can compare it with this

abc = 3dd = abc
dd = 43print(abc)  # 3,并不随dd的改变而改变
Copy after login

But if it is a copy, it is just copying the content, and what is passed is not Not quoted. This is especially useful when you want to use the values ​​of the list without modifying the original list.

blist = alist[:]  # or alist.copy()print(alist is blist)  # Falseblist.append(4)print(alist)  # 还是[1,2 ,3]没有变化
Copy after login

As a function parameter

As a function parameter, it is the same. Variable types pass references, while immutable types pass content.

test_list = [1, 2, 3, 4]
test_str = 'HAHA'def change(alist):
    alist.append(5)def not_change(astr):
    astr.lower()


change(test_list)
not_change(test_str)print(test_list)  # 改变了原来的值print(test_str)  # 没有变
Copy after login

Of course, if you don’t want to change the value of the original list, the parameters can be passed in a copy of the column variable. alsit[:]

Interesting example

Looking at another interesting example, we know that list can be added to a list using +.

a1 = [1, 2, 3]
a2 = a1print(id(a1), id(a2))# 实际上是a2指向了新的对象,id已经改变。# 所以现在a2、a1并不是同一对象的两个引用了,a2变化a1不会改变a2 = a2 + [4] # 这个等式中,右边的a2还是和a1的id一样的,一旦赋值成功,a2就指向新的对象print(id(1), id(a2))  # 不等,a2的id变化了print(a1) # [1, 2, 3]没有变
Copy after login

If it is written like this

a1 = [1, 2, 3]
a2 = a1print(id(a1), id(a2))
a2 += [4]  # 相当于调用了a2.extend([4]),原地改变并没有新的对象产生print(id(1), id(a2))  # 相等,a2的id没有变化print(a1)
Copy after login

The difference is that a2 += [4], this sentence is quite Because calling a2.extend([4]) is equivalent to changing in place, and no new objects are generated.

The above is the detailed content of Detailed explanation of mutable objects and immutable objects in Python. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!