Home  >  Article  >  Backend Development  >  An explanation of mutable objects and immutable objects in Python

An explanation of mutable objects and immutable objects in Python

零下一度
零下一度Original
2017-07-09 11:56:231852browse

The following editor will bring you a brief discussion of mutable objects and immutable objects in Python. The editor thinks it’s pretty good, so I’ll share it with you now and give it as a reference. Let’s follow the editor and take a look.

What is a mutable/immutable object

Immutable object, the memory pointed to by the object The value in 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. address.

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

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

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

Examples of immutable objects

Let’s first explain that is is to determine whether the ids of two objects are the same, and = = What is judged is whether the contents are the same.


a = 2
b = 2
c = a + 0 
c += 0

print(id(a), id(b), id(2)) # id都相同
print(c is b) #True

Look at the string


astr = 'good'
bstr = 'good'
cstr = astr + ''
print(cstr is bstr) # True
print(id(astr), id(bstr), id('good')) # 三个id相同

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和上面的不一样

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 again


##

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)

Although it seems that 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)没有变

is consistent with the numeric type and the str type. If it is a variable 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, and float, as long as they have the same type and the same value, then their ids will be the same. (Why do you say they are of the same type?)


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

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都不同

Look at the assignment


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

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

and look at the set


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

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 = 3
dd = abc
dd = 43
print(abc) # 3,并不随dd的改变而改变

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


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

As a function parameter

As a function parameter, it is the same, it is passed in a variable type It is a reference, and the immutable type passes the 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) # 没有变

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 = a1
print(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]没有变

If it is written like this


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

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

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

Statement:
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