神奇的python系列6:python基础数据类型补充

第一步  二次编码

ascii 不支持中文
gbk 支持中文 2个字节 包含ascii码
unicode 万国码 python3 内存unicode
utf-8 可变的长 英文 1 字节 欧洲2个字节 亚洲3个字节

在python中可以把⽂字信息进⾏编码. 编码之后的内容就可以进⾏传输了.编码之后的数据是bytes类型的数据.

s = "我叫李嘉诚"
print(s.encode("utf-8")) #编码
b'xe6x88x91xe5x8fxabxe6x9dx8exe5x98x89xe8xafx9a'
print(b'xe6x88x91xe5x8fxabxe6x9dx8exe5x98x89xe8xafx9a'.decode("utf-8")) # 解码

第二步  基础数据补充 # 坑

lst = [1,2,3,4,5,6]
 
for i in lst:
    lst.append(7) # 这样写法就会一直持续添加7      # 列表不能循环添加会变成死循环
    print(lst)
print(lst)

列表: 循环删除列表中的每⼀个元素

li = [11, 22, 33, 44]
for e in li:
 li.remove(e)     # 列表使用for循环删除元素   for循环的计数 删除不干净
print(li)
结果:
[22, 44]

分析原因: for的运⾏过程. 会有⼀个指针来记录当前循环的元素是哪⼀个, ⼀开始这个指针指向第0 个.然后获取到第0个元素. 紧接着删除第0个. 这个时候. 原来是第⼀个的元素会⾃动的变成 第0个.然后指针向后移动⼀次, 指向1元素. 这时原来的1已经变成了0, 也就不会被删除了.

如果⽤del删除呢?

li = [11, 22, 33, 44]
for i in range(0, len(li)):
 del li[i]
print(li)
结果: 报错
# i= 0, 1, 2 删除的时候li[0] 被删除之后. 后⾯⼀个就变成了第0个.
# 以此类推. 当i = 2的时候. list中只有⼀个元素. 但是这个时候删除的是第2个 肯定报错啊

经过分析发现. 循环删除都不⾏. 不论是⽤del还是⽤remove. 都不能实现. 

那么用pop呢?

for i in range(len(li)):      #
    li.pop()                  # 循环len(li)次, 然后从后往前删除
print(li)

或者. ⽤另⼀个列表来记录你要删除的内容. 然后循环删除

li = [1,2,3,4,5]              #
l2 = []
for i in li:
    l2.append(i)
for j in l2:
    li.remove(j)
print(li)
for i in li:
    li.clear()                  # 实在不行的话使用clear()删除
print(li)

注意: 由于删除元素会导致元素的索引改变, 所以容易出现问题. 尽量不要再循环中直接去删 除元素. 可以把要删除的元素添加到另⼀个集合中然后再批量删除.

dict中的fromkey(),可以帮我们通过list来创建⼀个dict。

但是dict.fromkeys()   #######################坑值是可变类型#########################

dic = dict.fromkeys('年后啊','消愁')

# 第一个位置是可迭代对象,也就是字典的键
# 第二个位置 不写是None  也就是字典的值
dic = dict.fromkeys(["jay", "JJ"], ["周杰伦", "麻花藤"])
print(dic)
结果:
{'jay': ['周杰伦', '麻花藤'], 'JJ': ['周杰伦', '麻花藤']}

代码中只是更改了jay那个列表.但是由于jay和JJ⽤的是同⼀个列表.所以,前⾯那个改了.后面那个也会跟着改。 

dict中的元素在迭代过程中是不允许进⾏删除的,那怎么办呢? 把要删除的元素暂时先保存在⼀个list中, 然后循环list, 再删除。

lst = []
for i in dic:
    lst.append(i)   # 每个字典的键
for j in lst:
    dic.pop(j)
print(dic)

类型转换:

  元组 => 列表 list(tuple)

  列表 => 元组 tuple(list)

  list=>str str.join(list)

  str=>list str.split()

  转换成False的数据:

   0,'',None,[],(),{},set() ==> False

第三步  深浅拷贝

浅拷⻉,只会拷⻉第⼀层. 第⼆层的内容不会拷⻉. 所以被称为浅拷⻉。

lst1 = ["何炅", "杜海涛","周渝⺠"]
lst2 = lst1.copy()
lst1.append("李嘉诚")
print(lst1)
print(lst2)
print(id(lst1), id(lst2))

浅拷贝只拷贝第一层元素,元素是不可变的,就不会变.元素是可变的俩个同时变。

深拷⻉,把元素内部的元素完全进行拷贝复制.不会产⽣⼀个改变另⼀个跟着改变的问题。

import copy   #深拷贝要引入copy方法
lst1 = ["何炅", "杜海涛","周渝⺠", ["麻花藤", "⻢芸", "周笔畅"]]
lst2 = copy.deepcopy(lst1)
lst1[3].append("⽆敌是多磨寂寞")
print(lst1)
print(lst2)
print(id(lst1[3]), id(lst2[3]))
结果:
['何炅', '杜海涛', '周渝⺠', ['麻花藤', '⻢芸', '周笔畅', '⽆敌是多磨寂寞']]
['何炅', '杜海涛', '周渝⺠', ['麻花藤', '⻢芸', '周笔畅']]
4447221448 4447233800

不可变数据类型共用一个内容,可变数据类型重新开辟空间存放内容。

# 面试题:

# li = [1,2]   # li = [1,[1,[1,[1,2]]]]
# li[1] = li
# print(li)
#  结果 [1, [...]]

第四步  is == 区别

==  比较两边的值            # 看这俩人是不是长得一样
is   比较两边的内存地址      # 判断是不是一个   身份证号
# is == 区别

# a = 1000
# b = 1000
# print(a == b)
# print(id(a))
# print(id(b))
# print(a is b)   # is 是

== 是比较的两边的数值是否相等,而 is 是比较的两边的内存地址是否相等。 如果内存地址相等,那么这两边其实是指向同一个内存地址。可以说如果内存地址相同,那么值肯定相同,但是如果值相同,内存地址不一定相同。这就要说到小数据池了。

第五步  小数据池 代码块(了解)

说小数据池首先的说一下什么是代码块。

代码块一个文件,模块,类,函数,cmd一行就是一个代码块。在python中内置,为了节省资源,提高效率。

代码块机制:

1.数字:范围  -5 ~ 256

2.字符串:字符串进行乘法的时候总长度不能超过20

3.bool:True和False在字典中会以1,0方式存在,并且复用

代码块的缓存机制的适用范围: int(float),str,bool

小数据池:也称为小整数缓存机制,或者称为驻留机制等等。在python中内置,小数据池是针对不同代码块之间的缓存机制!!!

小数据池驻留机制:

1.数字:范围  -5 ~ 256

2.字符串:字符串进行乘法的时候总长度不能超过20

3.bool值就是True,False,无论你创建多少个变量指向True,False,那么他在内存中只存在一个。

注意:小数据池也是只针对 int(float),str,bool

小结:

1.如果在同一代码块下,则采用同一代码块下的换缓存机制。

2.如果是不同代码块,则采用小数据池的驻留机制。

3.在同一文件下,先执行代码块,后执行小数据池。

数据类型总结:

# 面试题:  #####
# 用一行代码实现,字符串转成列表
s = '1111,2222,333,4444'
print(s.split(","))
# 用一行代码实现,列表转成字符串
lst = ['1','2','3']
print(''.join(lst))

不可变数据:字符串,数字(int),布尔值(bool),元祖

可变数据:列表,字典,集合

有序的数据: 列表(list),元祖(tuple),字符串(str)

无序的数据: 字典(dict),集合(set)

s = '{1:2}'
# print(dict(s))   # 字符串转字典不行
# print(list({1:'22',2:'44'}))  #结果:[1, 2] 
原文地址:https://www.cnblogs.com/xianyuwangzhe/p/10225678.html