Python基础Day7
七步记忆法:
① 预习(30min)
② 听课 (重点)
③ 课间练习
④ 下午或者晚上练习(大量练习、重复练习)
⑤ 晚上睡觉前的回忆
⑥ 第二天早晨回顾
⑦ 每周总结,自己默写方法
一、enumerate 枚举
对于一个可迭代的(iterable)/可遍历的对象(如列表、字符串),enumerate将其组成一个索引序列,利用它可以同时获得索引和值。
将可迭代对象以元组的形式展现。
遍历时用两个变量接受,一个变量接收序号,一个变量接收可迭代对象。
二、编码转换
一种非unicode编码转换为另一种非unicode编码,需要通过unicode来中转;
先解码为unicode编码,再编码为其他非unicode
b1 = b'\xb9\xfe\xb9\xfe' # gbk编码格式
s1 = b1.decode('gbk') # 解码成unicode编码
b2 = s1.encode('utf-8') # 转换为uft-8编码
print(b2)
# 结果
b'\xe5\x93\x88\xe5\x93\x88'
英文字母、数字、特殊字符可以通过其他编码的方式解码,因为utf-8 gbk,unicode等编码的英文字母,数字,特殊字符都是映射的ascii码
b1 = 'abc'.encode('gbk')
s2 = b1.decode('utf-8')
print(s2,type(s2))
# 结果
abc <class 'str'>
三、基础数据类型补充
① 字符串
isspace() # 判断字符串是否全部为空格,全部都是空格返回True,否则返回False
s1 = ' \n \t '
print(s1.isspace()) # 判断字符串是否全部为空格
s2 = ' a '
print(s2.isspace()) # 判断字符串是否全部为空格
# 结果
True
False
② 元组
元组只有一个元素,且没有逗号的情况,跟元素的数据类型一致
tu1 = ([1,2,3]) # 一个列表
tu2 = (1) # 一个数字
print(tu1,type(tu1))
print(tu2,type(tu2))
#结果
[1, 2, 3] <class 'list'>
1 <class 'int'>
只有一个元素,但是加了逗号,都视为元组
tu1 = ([1,2,3],)
tu2 = (1,)
print(tu1,type(tu1))
print(tu2,type(tu2))
# 结果
([1, 2, 3],) <class 'tuple'>
(1,) <class 'tuple'>
③ 列表
在循环一个列表时,如果对列表中的某些元素进行删除,那么此元素后面的所有元素就会前进一位,它们的索引就会发生变化
需求:lis = [11,22,33,44,55,66,77,88,99] 删除所有奇数索引的值
方法一:del 删除
#lis = [11,22,33,44,55,66,77,88,99] 删除所有奇数索引的值
lis = [11,22,33,44,55,66,77,88,99]
del lis[1::2]
print(lis)
# 结果
[11, 33, 55, 77, 99]
方法二: 将元素添加至新列表里
#lis = [11,22,33,44,55,66,77,88,99] 删除所有奇数索引的值
lis = [11,22,33,44,55,66,77,88,99]
lis2 = []
for i in range(len(lis)):
if i % 2 == 0:
lis2.append(lis[i])
lis = lis2
print(lis)
# 结果
[11, 33, 55, 77, 99]
方法三:倒序删除
#lis = [11,22,33,44,55,66,77,88,99] 删除所有奇数索引的值
lis = [11,22,33,44,55,66,77,88,99]
for i in range(len(lis)-1,-1,-1):
if i % 2 == 1:
lis.pop(i)
print(lis)
# 结果
[11, 33, 55, 77, 99]
总结:在循环一个列表时,尽量不要对此列表进行增和删的操作,否则会造成索引的变化。
列表与列表可以相加
l1 = [1,2,3]
l2 = ['a','b']
l3 = l1 + l2
print(l3)
# 结果
[1, 2, 3, 'a', 'b']
④ 字典
总结:循环一个字典时,不能改变字典的大小(即不能对字典进行增删操作)
# 对字典中的的键含有k的删除键值对
dic = {'key1': 'value1','key2': 'value2', 'k3':'v3', 'name': 'xiaoming','age':20}
li = []
for i in dic:
if 'k' in i:
li.append(i)
for j in li:
dic.pop(j)
print(dic)
# 结果
{'name': 'xiaoming', 'age': 20}
创建字典的方法
a. 直接创建
dic = {'name':'xiaoming','age':20}
print(dic)
# 结果
{'name': 'xiaoming', 'age': 20}
b. dict创建
dic = dict({'name':'xiaoming','age':18})
print(dic)
dic1 = dict((['name','xiaoming'],('age',20)))
dic2 = dict([('name','小黑'),['location','深圳']])
print(dic1)
print(dic2)
# 结果
{'name': 'xiaoming', 'age': 18}
{'name': 'xiaoming', 'age': 20}
{'name': '小黑', 'location': '深圳'}
c. 使用dict.fromkeys() 创建
dic = dict.fromkeys([1,2,3],['a','b','c'])
print(dic)
# 结果
{1: ['a', 'b', 'c'], 2: ['a', 'b', 'c'], 3: ['a', 'b', 'c']}
若使用fromkeys()方法创建的字典,值是可变数据类型(列表,字典,集合),所有的键指向的都是同一个
dic = dict.fromkeys([1,2,3],['a','b','c'])
print(dic)
dic[1].append('d') # 在值的容器里添加,所有的值都会变化,因为是同一个容器
print(dic)
dic[2] = []
print(dic)
# 结果
{1: ['a', 'b', 'c'], 2: ['a', 'b', 'c'], 3: ['a', 'b', 'c']}
{1: ['a', 'b', 'c', 'd'], 2: ['a', 'b', 'c', 'd'], 3: ['a', 'b', 'c', 'd']}
{1: ['a', 'b', 'c', 'd'], 2: [], 3: ['a', 'b', 'c', 'd']}
四、数据类型的转换
str ---> list # 使用字符串的方法split()
s1 = 'a b c d e'
lis = s1.split()
print(lis)
# 结果
['a', 'b', 'c', 'd', 'e']
list ---> str # 使用字符串的方法 join()
lis = ['a', 'b', 'c', 'd', 'e']
s1 = ''.join(lis)
print(s1)
# 结果
abcde
tuple ---> list # list(tuple)
lis = [1,2,3]
tu = tuple(lis)
print(tu)
# 结果
(1, 2, 3)
list ---> tuple # tuple(list)
tu = ('a','b','c')
lis = list(tu)
print(lis)
# 结果
['a', 'b', 'c']
dict ---> list # list(dict)
将字典转为列表,只能把字典的所有键转化为列表
dic = {1:'a',2:'b',3:'c'}
lis = list(dic)
print(lis)
# 结果
[1, 2, 3]
所有类型 ---> bool
s1 = ''
print(bool(s1)) # 空字符转换为bool是False
i = 0
print(bool(i)) # 0转换为bool是False
lis = []
print(bool(lis)) # 空列表转换为bool是False
tu = ()
print(bool(tu)) # 空元组转换为bool是False
dic = {}
print(bool(dic)) # 空字典转换为bool是False
set1 = set()
print(bool(set1)) # 空集合转换为bool是False
# 结果
False
False
False
False
False
False
五、集合
集合一般用于科学运算,大数据,后端开发使用集合相对比较少
集合的元素不重复,无序的
集合里的元素必须时不可变的数据类型(可哈希),但是集合本身是可变的数据类型
集合的主要用途:① 去重 ② 关系测试
重点:
A、列表去重(用集合去重)
lis = [1,1,2,3,5,9,6,3,6,5]
set1 = set(lis)
print(set1)
lis = list(set1)
print(lis)
# 结果
{1, 2, 3, 5, 6, 9}
[1, 2, 3, 5, 6, 9]
B、frozenset()
将集合变成不可变的数据类型
set1 = {1,2,3,4,5,6,7,8}
set2 = frozenset(set1)
print(set1,type(set1))
print(set2,type(set2))
# 结果
{1, 2, 3, 4, 5, 6, 7, 8} <class 'set'>
frozenset({1, 2, 3, 4, 5, 6, 7, 8}) <class 'frozenset'>
集合的创建
set1 = {1,2,3,'a','b','c'}
set2 = ({1,2,3,'a','b'})
print(set1)
print(set2)
# 结果
{1, 2, 3, 'a', 'c', 'b'}
{1, 2, 3, 'a', 'b'}
集合的增
set1 = {1,2,3,'a','b','c'}
set1.add('z')
print(set1)
# 结果
{1, 2, 3, 'z', 'a', 'c', 'b'}
set1 = {1,2,3,'a','b','c'}
set1.update([5,6,8])
print(set1)
# 结果
{1, 2, 3, 5, 6, 'b', 8, 'a', 'c'}
集合的删
set1 = {1,2,3,'a','b','c'}
set1.clear() # 清空集合
print(set1)
# 结果
set()
set1 = {1,2,3,'a','b','c'}
set1.remove(2) # 删除一个元素
print(set1)
# 结果
{'b', 1, 3, 'c', 'a'}
set1 = {1,2,3,'a','b','c'}
print(set1.pop()) # 随机删除一个元素,返回值是被删除的元素
print(set1)
# 结果
1
{2, 3, 'c', 'b', 'a'}
set1 = {1,2,3,'a','b','c'}
del set1 # 删除整个集合
关系测试
set1 = {1,2,3,'a','b','c'}
set2 = {'a','b',5,6,7}
set3 = set1 & set2 # 交集
set4 = set1.intersection(set2) # 交集
print(set3)
print(set4)
# 结果
{'b', 'a'}
{'b', 'a'}
set1 = {1,2,3,'a','b','c'}
set2 = {'a','b',5,6,7}
set3 = set1 | set2 # 并集
set4 = set1.union(set2) # 并集
print(set3)
print(set4)
# 结果
{1, 2, 3, 'b', 5, 6, 7, 'a', 'c'}
{1, 2, 3, 'b', 5, 6, 7, 'a', 'c'}
set1 = {1,2,3,'a','b','c'}
set2 = {'a','b',5,6,7}
set3 = set1 ^ set2 # 反交集
set4 = set1.symmetric_difference(set2) # 反交集
print(set3)
print(set4)
# 结果
{1, 2, 3, 5, 6, 7, 'c'}
{1, 2, 3, 5, 6, 7, 'c'}
set1 = {1,2,3,'a','b','c'}
set2 = {'a','b',5,6,7}
set3 = set1 - set2 # 差集
set4 = set1.difference(set2) # 差集
print(set3)
print(set4)
# 结果
{1, 2, 3, 'c'}
{1, 2, 3, 'c'}
set1 = {1,2,3}
set2 = {1,2,3,4,5,6}
print(set1 < set2) # set1 是 set2 的子集
print(set1.issubset(set2)) # set1 是 set2 的子集
# 结果
True
True
set1 = {1,2,3}
set2 = {1,2,3,4,5,6}
print(set2 > set1) # set2 是 set1 的超集
print(set2.issuperset(set1)) # set2 是 set1 的超集
# 结果
True
True
六、深浅拷贝copy
① 浅拷贝copy
l1 = [1,2,3]
l2 = l1.copy() # copy列表l1
l1.append(6)
print(l1 is l2)
print(l1)
print(l2)
结论:复制后的两个列表的id不同
l1 = [1,2,3,['a','b']]
l2 = l1.copy()
l1[-1].append('c') # 在列表里嵌套的列表追加元素
l1.append(5) # 在列表里追加元素
print(l1)
print(l2)
print(l1[3] is l2[3]) # 对比['a', 'b', 'c'] 是否同一个
# 结果
[1, 2, 3, ['a', 'b', 'c'], 5]
[1, 2, 3, ['a', 'b', 'c']]
True
结论:浅拷贝复制最外层是在内存中是独立的,从第二层以及更内层都是使用同一个的内存地址,内层变动复制后的内层也会跟着变动
对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,指向的都是同一个内存地址,所以,对于第二层以及更深的层数来说,保持一致性。
l1 = [1,2,3,['a','b']]
l2 = l1[:]
l1[-1].append('c') # 在列表里嵌套的列表追加元素
l1.append(5) # 在列表里追加元素
print(l1)
print(l2)
print(l1[3] is l2[3]) # 对比['a', 'b', 'c'] 是否同一个
# 结果
[1, 2, 3, ['a', 'b', 'c'], 5]
[1, 2, 3, ['a', 'b', 'c']]
True
结论:使用l2 = l1[:]复制也是浅拷贝
② 深拷贝ccopy
import copy
l1 = ['a','b','c',[6,7,8]]
l2 = copy.deepcopy(l1)
l1[-1].append(9)
l1.append('z')
print(l1)
print(l2)
# 结果
['a', 'b', 'c', [6, 7, 8, 9], 'z']
['a', 'b', 'c', [6, 7, 8]]
结论:深拷贝copy是完全独立的,原列表嵌套的内容进行修改也不会影响新列表
两个是完全独立的,改变任意一个的任何元素(无论多少层),另一个绝对不改变。
应用场景:面试会考,解释深浅copy
完全独立的copy一份数据,与原数据没有关系,深copy
如果一份数据(列表)第二层时,你想与原数据进行公用,浅copy。
八、昨日内容回顾
小数据池:
前提:int,str,bool
1,节省内存。
2,提高性能和效率。
在内存中,创建一个'池',提前存放了 -5 ~256 的整数,一定规则的字符串。
后续程序中,如果设置的变量指向的是小数据池的内容,那么就不会再内存中重新创建。
小数据池与代码块的关系:
同一个代码块:python在执行时,遇到了初始化对象命令,他会将这个变量名和数值放到一个字典中,
再次遇到他会从这字典中寻找。
不同代码块:python在执行时,直接从小数据池中寻找,满足条件id相同。