7.深浅拷贝
1. 基础数据类型补充
首先关于int和str在之前的学习中已经讲了80%以上了. 所以剩下的自己看一看就可以了. 我们补充给⼀一个字符串基本操作
join()
获取到的每个元素和前面的进行拼接. 得到的是字符串
lst = ["alex","dsb","wusir","xsb"] s = "_".join(lst) print(s) #alex_dsb_wusir_xsb
split()
切割的结果是列表
s = "alex_dsb_wusir_xsb" lst = s.split("_")#列表 print(lst) #['alex', 'dsb', 'wusir', 'xsb']
列表循环删除列表的每一个元素
li = [11,22,33,44] for e in li: li.remove(e) print(li) #[22,44]
列表和字典: 都不能在循环的时候直接删除
而是把要删除的内容记录在新列表中然后循环这个新列表. 删除列表(字典)
lst = ["篮球","排球","足球","电子竞技","排球"] new_lst = [] for el in lst: if "球" in el: new_lst.append(el) print(new_lst)#['篮球', '排球', '足球', '排球'] for i in new_lst: lst.remove(i) print(lst)#['电子竞技']
报错的代码
dic = {"张无忌":"乾坤大挪移", "周芷若":"哭", "赵敏":"卖萌"} for k in dic: dic.pop(k) # dictionary changed size during iteration dic["灭绝师太"] = "倚天屠龙剑"
运行报错的原因:
for的运行过程. 会有一个指针来记录当前循环的元素是哪一个, 一开始这个指针指向第0 个. 然后获取到第0个元素. 紧接着删除第0个. 这个时候. 原来是第一个的元素会自动的变成第0个. 然后指针向后移动一次, 指向1元素. 这时原来的1已经变成了0, 也就不会被删除了.
fromkeys()
把第一个参数进行迭代. 拿到每一项作为key和后面的value组合成字典
坑1: 返回新字典. 不会更改老字典
dic = {} d = dic.fromkeys("风扇哥", "很困") print(dic) # {} print(d)#{'风': '很困', '扇': '很困', '哥': '很困'}
坑2: 当value是可变的数据类型. 各个key共享同一个可变的数据类型. 其中一个被改变了. 其他都跟着变
d = dict.fromkeys("胡辣汤", []) print(d) # {'胡': [], '辣': [], '汤': []} print(id(d['胡']))#2679822994120 print(id(d['辣']))#2679822994120 print(id(d['汤']))#2679822994120 d['胡'].append("河南特色") print(d) # {'胡': ['河南特色'], '辣': ['河南特色'], '汤': ['河南特色']}
# 程序员找工作和菜市场大妈买白菜是一样的
dict中的元素在迭代过程中是不允许进行删除的
dic = {"k1":"alex",'k2':'wusir','s1':'金老板'} # 删除key带'k'的元素 for k in dic: if 'k' in k: del dic[k] #dictionary changed size during iteration # 代的时候不允许进行删除操作 print(dic)
那怎么办呢? 把要删除的元素暂时先保存在一个list中, 然后循环list, 再删除
dic = {"k1":"alex",'k2':'wusir','s1':'金老板'} dic_new = [] # 删除key带'k'的元素 for k in dic: if 'k' in k: dic_new.append(k) for el in dic_new: del dic[el] print(dic)
类型转换:
元组=>列表 list(tuple)
列表 =>元组 tuple(list)
list =>str str.join(list)
str =>list str.split()
转换成False的数据:
0,' ',,None,[],{},set() ==>False
set集合
set集合是python的一个基本数据类型. 一般不是很常用. set中的元素是不重复的.无序的.里面的元素必须是可hash的(int, str, tuple,bool), 我们可以这样来记. set就是dict类型的数据但是不保存value, 只保存key. set也用{}表示
注意: set集合中的元素必须是可hash的, 但是set本身是不可hash得. set是可变的
set1 = {'1','alex',2,True,[1,2,3]}# 报错list set2 = {'1','alex',2,True,{1:2}}# 报错dict set3 = {'1','alex',2,True,(1,2,[2,3,4])} # 报错list
set中的元素是不重复的, 且无序的.
s = {"周杰伦","周杰伦","周星驰"} print(s) #{'周星驰', '周杰伦'}
用这个特性.我们可以使用set来去掉重复
lst = [45,5,"哈哈",45,"哈哈",50] lst = list(set(lst)) # 把list转换成set, 然后再转换回list print(lst)#[5, 50, '哈哈', 45]
set集合的增删改查
1.增加
s = {'alex','wusir','小钱'} s.add('太白') print(s)#{'wusir', '小钱', '太白', 'alex'} s.add("小钱") #重复的内容不会添加到set集合 print(s)#{'wusir', '小钱', '太白', 'alex'} s = {'alex','wusir','小钱'} s.update("太白") #迭代更新 print(s)#{'alex', 'wusir', '白', '小钱', '太'} s.update(["成龙","吴斌","张智成"]) print(s)#'alex', '张智成', 'wusir', '白', '小钱', '太', '吴斌', '成龙'}
2.删除
s = {'alex','wusir','小钱',"成龙","吴斌"} item = s.pop()#随机弹出一个 print(s)#{'吴斌', 'alex', '小钱', '成龙'} print(item)#wusir s.remove("吴斌") print(s)#{'小钱', '成龙', 'alex', 'wusir'} s.remove("sb") #不存在这个元素,删除会报错 s.clear()# #清空set集合.需要注意的是set集合如果是空的. 打印出来是set() 因为要和dict区分的. print(s) #set()
3.修改
# set集合中的数据没有索引. 也没有办法去定位一个元素. 所以没有办法进行直接修改. # 我们可以采用先删除后添加的方式来完成修改操作 s = {'alex','wusir','小钱',"成龙","吴斌"} s.remove("小钱") s.add("张智成") print(s)
4.查询
# set是一个可迭代对象. 所以可以进行for循环 for el in s: print(el)
5.常用操作
s1 = {"刘能", "赵四", "皮长山"} s2 = {"刘科长", "冯乡长", "皮长山"} # 交集 # 两个集合中的共有元素 print(s1 & s2) #{'皮长山'} print(s1.intersection(s2))#{'皮长山'} #并集 print(s1 | s2) #{'皮长山', '刘科长', '刘能', '冯乡长', '赵四' print(s1.union(s2)) #{'冯乡长', '皮长山', '刘科长', '赵四', '刘能'} #差集 print(s1 - s2)#{'刘能', '赵四'} print(s1.difference(s2))#{'刘能', '赵四'} #反交集 print(s1^s2)#{'赵四', '刘能', '冯乡长', '刘科长'} print(s1.symmetric_difference(s2))#{'赵四', '刘能', '冯乡长', '刘科长'} #子集 s1 = {"刘能", "赵四"} s2 = {"刘能", "赵四", "皮长山"} print(s1<s2)#True print(s1.intersection(s2))#{'刘能', '赵四'} #超集 print(s1>s2)#False print(s1.issuperset(s2))#False
set集合本身是可以发生改变的. 是不可hash的. 我们可以使用frozenset来保存数据. frozenset是不可变的. 也就是一个可哈希的数据类型
s = frozenset(["赵本山", "刘能", "皮长山", "⻓长跪"]) dic = {s:"123"} print(dic) #{frozenset({'刘能', '长跪', '皮长山', '赵本山'}): '123'}
不是很长用,了解
2. 深浅拷贝(重点, 难点)
1. = 没有创建新对象, 只是把内存地址进行了复制
lst1 = ["胡辣汤","灌汤包","油泼面","麻辣香锅",["长白山","白洋淀"]] lst2 = lst1 print(id(lst1))#2716046999880 print(id(lst2))#2716046999880 print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']] print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']] lst1.append("葫芦娃") print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀'], '葫芦娃'] print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀'], '葫芦娃']
对于list, set, dict来说, 直接赋值. 其实是把内存地址交给变量. 并不是复制一份内容. 所以lst1的内存指向和lst2是一样的. lst1改变了, lst2也发生了改变
2. 浅拷贝 .copy() 只拷贝第一层.
lst1 = ["胡辣汤","灌汤包","油泼面","麻辣香锅",["长白山","白洋淀"]] lst2 = lst1.copy() print(id(lst1))#2716046999816 print(id(lst2))#2716046999688 print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']] print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']] lst1[4].append("葫芦娃") print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀', '葫芦娃']] print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀', '葫芦娃']]
3. 深拷贝
import copy
copy.deepcopy() 会把对象内部的所有内容进行拷贝
import copy lst1 = ["胡辣汤","灌汤包","油泼面","麻辣香锅",["长白山","白洋淀"]] lst2 = copy.deepcopy(lst1) print(id(lst1))#2814635261768 print(id(lst2))#2814635360520 print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']] print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']] lst1.append("葫芦娃") print(lst1)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀'], '葫芦娃'] print(lst2)#['胡辣汤', '灌汤包', '油泼面', '麻辣香锅', ['长白山', '白洋淀']]
都不一样了. 深度拷贝. 把元素内部的元素完全进行拷贝复制. 不会产生一个改变另一个跟着改变的问题
一. 昨日内容回顾 小数据池 针对的数据类型: int, str, bool 小数据池可以帮我们缓存一个对象. 当重复使用的时候可以快速的响应. 直接把对象返回. 优点: 快速拿到对象, 节省内存 缺点: 当小数据池中的内容太多的时候. 程序响应速度是很慢的. is和== is 比较的是内存地址. == 比较的是内容 encode() : 可以帮我们把字符串转换成bytes类型 decode() : 把bytes类型还原回字符串类型 bytes是字节. 是python中最小的数据单元 二. 作业讲解 三. 今日主要内容 1. 基础数据类型补充 大多数的基本数据类型的知识.已经学完了 join() "*".join("马虎疼") # 马*虎*疼 把传递进去的参数进行迭代. 获取到的每个元素和前面的*进行拼接. 得到的是字符串 split() 切割. 切割的结果是列表 列表和字典: 都不能在循环的时候直接删除 把要删除的内容记录在新列表中然后循环这个新列表. 删除列表(字典) fromkeys() 坑1: 返回新字典. 不会更改老字典 坑2: 当value是可变的数据类型. 各个key共享同一个可变的数据类型. 其中一个被改变了. 其他都跟着变 # 程序员找工作和菜市场大妈买白菜是一样的 2. 深浅拷贝(重点, 难点) 1. = 没有创建新对象, 只是把内存地址进行了复制 2. 浅拷贝 lst.copy() 只拷贝第一层. 3. 深拷贝 import copy copy.deepcopy() 会把对象内部的所有内容进行拷贝 预习: 文件操作(本身简单, 联合其他知识进行操作. 会很烦) open() read write append
面试题
a = [1,2] a[1] = a print(a[1])
答案
[1,[...]]
作业