文章目录
- 一、基础知识补充
- 1、id()
- 2、is和==的区别
- 3、’ '.join( )
- 二、深浅拷贝
- 1、浅拷贝
- 2、深拷贝
- 3、为什么有深浅拷贝?
- 三、编码encode( )
- 四、解码decode( )
一、基础知识补充
1、id()
通过id( )我们可以查看到一个变量表示的值在内存中的地址
a = '1234abcd'
b = '1234abcd'
c = '12345678'
print(id(a)) # 64823984
print(id(b)) # 64823984
print(id(c)) # 64889456
2、is和==的区别
通过id( )计算出来的结果,比较数据对象的内存地址,我们可以查看两个变量使用的是否为同一对象
# == 双等表示的是判断数据的值是否相等
# is判断数据的内存地址是否相等
s1 = "哈哈"
s2 = "哈哈"
print(s1 == s2) # True
print(s1 is s2) # True 因为有小数据池所以变量地址相同
l1 = [1, 2, 3]
l2 = [1, 2, 3]
print(l1 == l2) # True
print(l1 is l2) # False
小数据池:
对于整数,Python官方文档中这么说:
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. </font>
对于字符串:
Incomputer science, string interning is a method of storing only onecopy of each distinct string value, which must be immutable. Interning strings makes some stringprocessing tasks more time- or space-efficient at the cost of requiring moretime when the string is created or interned. The distinct values are stored ina string intern pool. –引自维基百科 </font>
表达的意思就是:
Python自动将-5~256的整数进行了缓存,当你将这些整数赋值给变量时,并不会重新创建对象,而是使用已经创建好的缓存对象。
python会将一定规则的字符串在字符串驻留池中,创建一份,当你将这些字符串赋值给变量时,并不会重新创建对象, 而是使用在字符串驻留池中创建好的对象。
建议参考大佬们的文档:
唯唯诺诺的个人理解:我们创建代码的时候系统会自动创建内存地址用来代码运行,小数据池是把整数、字符串、bool这种占用空间小的数据固定存储起来,我们要用的时候,直接去系统提前存好的的空间取,不用再次创建新的空间,从而节省内存空间(对比大佬们详细的解答,感觉自己弱爆了 QAQ捂脸)
3、’ '.join( )
官文:The string whose method is called is inserted in between each given string.
The result is returned as a new string.
翻译:调用其方法的字符串插入到每个给定字符串之间。
结果将作为新字符串返回。
a = 'abc'
a1 = a.join('123') # 把字符串a插入到'123'中
print(a1) # 1abc2abc3
s = '_'.join(['abc','def','ghe'])
print(s) # abc_def_ghe
print(type(s)) # <class 'str'>
# 结果总结:' '.join()能把列表变成字符串,而把字符串变成列表用str.split()
二、深浅拷贝
# 创建列表进行赋值,系统开辟一个内存空间存放列表
lst = ['123','abc','ABC','6441dsfsag']
print(id(lst)) # 59269704 赋值 ————> lst内存空间
lst1 =['123','abc','ABC','6441dsfsag']
print(id(lst1)) # 59269768 赋值 ————> lst1内存空间
# 两个列表包含元素相同,但是内存空间不同
lst = ['123','abc','ABC','6441dsfsag']
lst1 = lst # 此时lst 与 lst1 公用一个内存空间 赋值lst1 ————> lst内存空间
lst1.append('qr@^%*G1') # 因为共用同一块内存空间,对一个赋值进行操作,两个赋值的结果都会变
print(lst) # ['123', 'abc', 'ABC', '6441dsfsag', 'qr@^%*G1']
print(lst1) # ['123', 'abc', 'ABC', '6441dsfsag', 'qr@^%*G1']
print(id(lst)) # 59269704
print(id(lst1)) # 59269704
1、浅拷贝
# .copy() 浅拷贝:拷贝父对象,但是不会拷贝对象的内部的子对象,创建新的父类内存空间,共用子类内存空间
lst2 = ['脆脆鲨','葡萄','奶茶']
lst3 = lst2.copy() # lst2和lst3不是同一个内存空间
lst2.append('果冻') # lst2列表添加父对象,lst3并不拷贝
print(lst2) # ['脆脆鲨', '葡萄', '奶茶', '果冻']
print(lst3) # ['脆脆鲨', '葡萄', '奶茶']
print(id(lst2),id(lst3)) # 57238088 57238152
lst2 = [['脆脆鲨', '葡萄', '奶茶'], '西瓜', '圆筒']
lst3 = lst2.copy()
lst2[0].append('果冻') # lst2列表添加子对象,lst3中拷贝来的子对象元素相同
print(lst2) # [['脆脆鲨', '葡萄', '奶茶', '果冻'], '西瓜', '圆筒']
print(lst3) # [['脆脆鲨', '葡萄', '奶茶', '果冻'], '西瓜', '圆筒']
print(id(lst2),id(lst3)) # 63054088 63087176
print(id(lst2[0]),id(lst3[0])) # 57041480 57041480
使用方法2:导入import copy 使用 lst3 = copy.copy(lst2) 方式也可以进行浅拷贝
2、深拷贝
# .deepcopy() 深拷贝:完全拷贝所有对象,父对象、子对象全部创建新的内存空间
import copy # 需要导入模块
list1 = [['脆脆鲨', '葡萄', '奶茶', '果冻'], ['西瓜', '圆筒', '蛋黄酥'],'麻辣烫']
list2 = copy.deepcopy(list1) # 把list1所有的内容进行深度拷贝,包括内部的所有内容进行拷贝
list1[1].append('芝士蛋糕')
print(list1) # [['脆脆鲨', '葡萄', '奶茶', '果冻'], ['西瓜', '圆筒', '蛋黄酥', '芝士蛋糕'], '麻辣烫']
print(list2) # [['脆脆鲨', '葡萄', '奶茶', '果冻'], ['西瓜', '圆筒', '蛋黄酥'], '麻辣烫']
print(id(list1),id(list2)) # 64781768 65078600
print(id(list1[0]),id(list2[0])) # 64926280 65078152
3、为什么有深浅拷贝?
因为:拷贝比创建对象的过程要快
三、编码encode( )
bytes的表现形式:
1. 英文 b’ali’ 英文的表现形式和字符串没什么两样
2. 中文 b’\xe4\xb8\xad’ 这是一个汉字的UTF-8的bytes表现形式
s = "ali"
print(s.encode("utf-8")) # b'ali' 将字符串编码成UTF-8
print(s.encode("GBK")) # b'ali' 将字符串编码成GBK
s = "中"
print(s.encode("UTF-8")) # b'\xe4\xb8\xad' 中文编码成UTF-8
print(s.encode("GBK")) # b'\xd6\xd0' 中文编码成GBK
四、解码decode( )
用什么方式编码,用什么方式解码
s = "我叫xxx"
print(s.encode("utf-8")) # 编码:b'\xe6\x88\x91\xe5\x8f\xabxxx'
print(b'\xe6\x88\x91\xe5\x8f\xabxxx'.decode('utf-8')) # 解码:我叫xxx
print(b'\xe6\x88\x91\xe5\x8f\xabxxx'.decode('GBK')) # 解码:鎴戝彨xxx ???否则就乱码看不懂了
s = "我是文字"
wz = s.encode("GBK") # 我们这样可以获取到GBK的文字
# 把GBK转换成UTF-8
# 首先要把GBK转换成unicode. 也就是需要解码
s = wz.decode("GBK") # 解码
# 然后需要进行重新编码成UTF-8
wzz = s.encode("UTF-8") # 重新编码
print(wzz) # b'\xe6\x88\x91\xe6\x98\xaf\xe6\x96\x87\xe5\xad\x97'