标签:内存 直接 增删改 完成 李嘉诚 怎么办 sig remove index
set集合,深浅拷贝以及部分知识点补充
一、基础数据类型补充
1、str.join()
join可以把列表变成字符串
split可以把字符串变成列表
实例:
(1)join可以把列表变成字符串
1 s = ‘abc‘
2 s1 = s.join(‘非常可乐‘) #把字符串s插入到‘非常可乐‘中
3 print(s1)
4 # >>> 非abc常abc可abc乐
5 s2 = "常可".join("非乐")
6 print(s2)
7 # >>> 非常可乐
8 s3 = "_".join(["alex", "wuse", "taibai", "ritian"]) # join可以把列表变成字符串,把字符串变成列表.split()
9 print(s3)
10 # >>>
alex_wuse_taibai_ritian
11 s4 = "游戏".join(["王者荣耀", "LOL", "跑跑卡丁车"])
12 print(s4)
13 # >>> 王者荣耀游戏LOL游戏跑跑卡丁车
(2)split可以把字符串变成列表
1 s = ‘alex.wusir.taibai.ritian.wuchao.yantao‘
2 ls = s.split(‘.‘)
3 print(ls)
4 # >>>[‘alex‘, ‘wusir‘, ‘taibai‘, ‘ritian‘, ‘wuchao‘, ‘yantao‘]
2、类型转换
元组 => 列表 list(tuple)
列表 => 元组 tuple(list)
list => str str.join(list)
str => list str.split()
转换成False的数据: 0,‘‘,None,[],(),{},set() ==> False
3、循环删除
(1)由于删除元素会导致元素的索引改变,所以容易出现问题,尽量不要在循环中直接去删除元素,可以把要删除的元素添加到另一个几个中,然后再批量删除。
不能用循环删除的有列表和字典for range()。
1) 列表——错误的循环删除remov:
1 li = [11, 22, 33, 44]
2 for e in li:
3 li.remove(e)
4 print(li)
5 # 结果:
6 # >>> [22, 44]
2)列表——错误的循环删除pop
1 li = [11, 22, 33, 44]
2 for el in li:
3 li.pop() # pop也不?
4 print(li)
5 # 结果:
6 # >>> [11, 22]
3)列表——错误的循环删除del
1 li = [11, 22, 33, 44]
2 for i in range(0, len(li)):
3 del li[i]
4 print(li)
5 # 结果:
6 # >>> 报错“IndexError: list assignment index out of range”
7 # i= 0, 1, 2 删除的时候li[0] 被删除之后. 后??个就变成了第0个.
8 # 以此类推. 当i = 2的时候.list中只有?个元素. 但是这个时候删除的是第2个肯定报错啊
(2)只有这样才是可以的:
1)循环len(li)次, 然后从后往前删除
1 li = [11, 22, 33, 44]
2 for i in range(0, len(li)): # 循环len(li)次, 然后从后往前删除
3 li.pop()
4 print(li)
5 # 结果:>>> []
2)?另?个列表来记录你要删除的内容. 然后循环删除
1 li = [11, 22, 33, 44]
2 del_li = []
3 for e in li:
4 del_li.append(e)
5 for e in del_li:
6 li.remove(e)
7 print(li)
8 # 结果:>>> []
(3)字典(dict)中的元素在迭代过程中也是不允许进?删除的:
1 # 删除key中带有‘k‘的元素
2 dic = {‘k1‘: ‘alex‘, ‘k2‘: ‘wusir‘, ‘s1‘: ‘??板‘}
3 for k in dic:
4 if ‘k‘ in k:
5 del dic[k] # dictionary changed size during iteration, 在循环迭代的时候不允许进行删除操作
6 print(dic)
7 # 结果:>>> 报错 RuntimeError: dictionary changed size during iteration(运行时错误:字典在迭代过程中改变了大小)
(4)那怎么办呢? 把要删除的元素暂时先保存在?个list中, 然后循环list, 再删除
1 # 删除key中带有‘k‘的元素
2 dic = {‘k1‘: ‘alex‘, ‘k2‘: ‘wusir‘, ‘s1‘: ‘??板‘}
3 dic_del_list = []
4 for k in dic:
5 if ‘k‘ in k:
6 dic_del_list.append(k)
7 for el in dic_del_list:
8 del dic[el]
9 print(dic)
10 # 结果:>>> {‘s1‘: ‘??板‘}
4、dict.fromkey()
(1)dict中的fromkey(),可以帮我们通过list来创建?个value相同的dict。
(2)fromkeys返回新列表,返回的是新列表、新列表、新列表!
1)格式:dict = dict.fromkes([list of key],[value])
2)前?列表中的每?项都会作为key, 后?列表中的整体内容作为value. ?成dict
1 dic = dict.fromkeys(["jay", "JJ"], ["周杰伦", "麻花藤"])
2 print(dic)
3 # 结果:>>> {‘jay‘: [‘周杰伦‘, ‘麻花藤‘], ‘JJ‘: [‘周杰伦‘, ‘麻花藤‘]}
3)下列代码中只是更改了jay那个列表. 但是由于jay和JJ?的是同?个列表. 所以. 前?那个改了. 后 ?那个也会跟着改。
1 dic = dict.fromkeys(["jay", "JJ"], ["周杰伦", "麻花藤"])
2 print(dic)
3 dic.get("jay").append("胡?")
4 print(dic)
5 # 结果:>>> {‘jay‘: [‘周杰伦‘, ‘麻花藤‘], ‘JJ‘: [‘周杰伦‘, ‘麻花藤‘]}
6 # 结果:>>> {‘jay‘: [‘周杰伦‘, ‘麻花藤‘, ‘胡?‘], ‘JJ‘: [‘周杰伦‘, ‘麻花藤‘, ‘胡?‘]}
4)fromkeys返回新列表,返回的是新列表、新列表、新列表(面试题)
############fromkeys返回新列表,返回的是新列表、新列表、新列表##############
dic = {‘a‘: ‘123‘}
s = dic.fromkeys(‘王健林‘,‘思聪‘) # dic.fromkeys 都可以
s1 = dict.fromkeys(‘王健林‘,‘思聪‘) # dict.fromkes 都可以
print(dic)
print(s)
print(s1)
# 结果:>>> {‘a‘: ‘123‘}
# 结果:>>> {‘王‘: ‘思聪‘, ‘健‘: ‘思聪‘, ‘林‘: ‘思聪‘}
# 结果:>>> {‘王‘: ‘思聪‘, ‘健‘: ‘思聪‘, ‘林‘: ‘思聪‘}
二、set集合
1、定义:
set集合是python的一个基本数据类型,一般不是很常用。set中的元素是不重复的,无序的,里边的元素必须是可hash的(int、str、tuple、bool)即使是嵌套的其他类型中嵌套了不可hash的类型也不可以。我们可以这样来记,set就是dict类型的数据,但是不保存value,只保存key。set也用{}表示。
注意:set集合中的元素必须是可以hash的,但是set本身是不可以hash的,set是可变的,所以set不可以嵌套
1)里边的元素必须是可hash的(int、str、tuple、bool)即使是嵌套的其他类型中嵌套了不可hash的类型也不可以。
1 set1 = {‘1‘,‘alex‘,2,True,[1,2,3]} # 报错
2 set2 = {‘1‘,‘alex‘,2,True,{1:2}} # 报错
3 set3 = {‘1‘,‘alex‘,2,True,(1,2,[2,3,4])} # 报错
2)set中的元素是不重复的,且无序的。
1 s = {"周杰伦", "周杰伦", "周星星"}
2 print(s)
3 # 结果:>>> {‘周星星‘, ‘周杰伦‘}
3)使用这个特性,我们可以使用set来去掉重复。
1 # 给list去重复
2 lst = [45, 5, "哈哈", 45, ‘哈哈‘, 50]
3 lst = list(set(lst)) # 把list转换成set, 然后再转换回list
4 print(lst)
5 # 结果:>>> [5, 50, 45, ‘哈哈‘]
4)我们可以使用frozenset来保存数据,frozenset是不可变的,也就是一个可hash的数据类型。
1 s = frozenset(["赵本?", "刘能", "???", "?跪"])
2 dic = {s:‘123‘} # 可以正常使?了
3 print(dic)
4 # 结果:>>> {frozenset({‘刘能‘, ‘???‘, ‘赵本?‘, ‘?跪‘}): ‘123‘}
2、set集合增删改查
(1)增加
.add() ——()中的内容整体新增进去。
.update() ——()中的内容迭代新增进去。
1) .add() ——()中的内容整体新增进去。
1 s = {"刘嘉玲", ‘关之琳‘, "王祖贤"}
2 s.add("郑裕玲")
3 print(s)
4 # 结果:>>> {‘王祖贤‘, ‘刘嘉玲‘, ‘关之琳‘, ‘郑裕玲‘}
1 s = {"刘嘉玲", ‘关之琳‘, "王祖贤"}
2 s.add(("刘嘉玲", ‘关之琳‘))
3 print(s)
4 # 结果:>>> {‘刘嘉玲‘, ‘关之琳‘, (‘刘嘉玲‘, ‘关之琳‘), ‘王祖贤‘}
重复的内容不会被添加到set中
1 s = {"刘嘉玲", ‘关之琳‘, "王祖贤","郑裕玲"}
2 s.add("郑裕玲") # 重复的内容不会被添加到set集合中
3 print(s)
4 # 结果:>>> {‘刘嘉玲‘, ‘王祖贤‘, ‘郑裕玲‘, ‘关之琳‘}
2).update() ——()中的内容迭代新增进去。
1 s = {"刘嘉玲", ‘关之琳‘, "王祖贤"}
2 s.update("麻花藤") # 迭代更新
3 print(s)
4 # 结果:>>> {‘关之琳‘, ‘藤‘, ‘麻‘, ‘刘嘉玲‘, ‘花‘, ‘王祖贤‘}
1 s = {"刘嘉玲", ‘关之琳‘, "王祖贤"}
2 s.update(("刘嘉玲", ‘关之琳‘,"周润发")) # 迭代进去的话,"刘嘉玲",和‘关之琳‘已经有了,不再添加,"周润发"没在,添加。
3 print(s)
4 # 结果:>>> {‘刘嘉玲‘, ‘周润发‘, ‘关之琳‘, ‘王祖贤‘}
(2)删除
s.pop() —— 随机删除一个。删除的内容可以被接收。
.remove(元素) —— 直接删除()中的元素,不存在这个元素会报错。
.clear() —— 清空set集合,注意:如果set集合是空的,打印出来的结果是set(),因为要和dict区分。
1) s.pop() —— 随机删除一个元素,删除掉的元素是可以被接收的。
1 s = {"刘嘉玲", ‘关之琳‘, "王祖贤","张曼?", "李若彤"}
2 item = s.pop() # 随机弹出?个.
3 print(s)
4 print(item)
5 # 结果:>>> {‘王祖贤‘, ‘关之琳‘, ‘张曼?‘, ‘李若彤‘}
6 # 结果:>>> 刘嘉玲
2).remove(元素) —— 通过元素,直接删除()中的元素。但是元素不存在的时候会报错。
1 s = {"刘嘉玲", ‘关之琳‘, "王祖贤","张曼?", "李若彤"}
2 s.remove("关之琳") # 直接删除元素
3 print(s)
4 # 结果:>>> {‘刘嘉玲‘, ‘李若彤‘, ‘张曼?‘, ‘王祖贤‘}
1 s = {"刘嘉玲", ‘关之琳‘, "王祖贤","张曼?", "李若彤"}
2 s.remove("??疼") # 不存在这个元素. 删除会报错
3 print(s)
4 # 结果:>>> KeyError: ‘??疼‘
1 s = {"刘嘉玲", ‘关之琳‘, "王祖贤","张曼?", "李若彤"}
2 s.clear() # 清空set集合.需要注意的是set集合如果是空的. 打印出来是set() 因为要和dict区分的.
3 print(s) # set()
4 print(type(s))
5 # 结果:>>> set()
6 # 结果:>>> <class ‘set‘>
(3)修改
set集合中的数据是无序的,也没有索引,也没有办法去定位一个元素,所以没有办法直接进行修改,只能采用先删除后增加的方式来完成修改操作。
先set.remove()
再set.add()
1 # 把刘嘉玲改成赵本?
2 s = {"刘嘉玲", ‘关之琳‘, "王祖贤","张曼?", "李若彤"}
3 s.remove("刘嘉玲")
4 s.add("赵本?")
5 print(s)
6 # 结果:>>> {‘王祖贤‘, ‘关之琳‘, ‘张曼?‘, ‘李若彤‘, ‘赵本?‘}
(4)查询
set是一个可迭代对象,所以可以进行for循环。
s = {"刘嘉玲", ‘关之琳‘, "王祖贤"}
for el in s:
print(el)
# 结果:>>> 刘嘉玲
# 结果:>>> 关之琳
# 结果:>>> 王祖贤
(5)常用操作
每个操作都有2中表达方式,符号表达方式和单词表达方式:
名称 - 符号 - 单词
交集 - & - intersection # 两个集合中共有的元素
并集 - | - union #两个集合合并去重后的元素
差集 - - - difference #得到第一个中单独存在的
反交集 - ^ - symmetric_difference #两个集合中不重复的数据和
子集 - < - issubset # 包含于
超集 - > - issuperset #包含
1)交集 - & - intersection # 两个集合中共有的元素
1 # 交集——两个集合中的共有元素
2 s1 = {"刘能", "赵四", "皮长山"}
3 s2 = {"刘科长", "冯乡长", "皮长山"}
4 print(s1 & s2) # {‘???‘}
5 print(s1.intersection(s2)) # {‘???‘}
6 # 结果:>>> {‘???‘}
7 # 结果:>>> {‘???‘}
2)并集 - | - union #两个集合合并去重后的元素
1 # 并集——两个集合合并去重后的元素
2 s1 = {"刘能", "赵四", "皮长山"}
3 s2 = {"刘科长", "冯乡长", "皮长山"}
4 print(s1 | s2)
5 print(s1.union(s2))
6 # 结果:>>> {‘冯乡长‘, ‘刘能‘, ‘皮长山‘, ‘赵四‘, ‘刘科长‘}
7 # 结果:>>> {‘冯乡长‘, ‘刘能‘, ‘皮长山‘, ‘赵四‘, ‘刘科长‘}
3)差集 - - - difference #得到第一个中单独存在的
1 # 差集——得到第一个中单独存在的
2 s1 = {"刘能", "赵四", "皮长山"}
3 s2 = {"刘科长", "冯乡长", "皮长山"}
4 print(s1 - s2) # {‘赵四‘, ‘刘能‘} 得到第?个中单独存在的
5 print(s1.difference(s2)) # {‘赵四‘, ‘刘能‘}
6 # 结果:>>> {‘刘能‘, ‘赵四‘}
7 # 结果:>>> {‘刘能‘, ‘赵四‘}
4)反交集 - ^ - symmetric_difference #两个集合中不重复的数据和
1 # 反交集——两个集合中不重复的数据和
2 s1 = {"刘能", "赵四", "皮长山"}
3 s2 = {"刘科长", "冯乡长", "皮长山"}
4 print(s1 ^ s2) # 两个集合中单独存在的数据
5 print(s1.symmetric_difference(s2)) # {‘赵四‘, ‘刘科长‘, ‘冯乡长‘, ‘刘能‘}
6 # 结果:>>> {‘赵四‘, ‘刘科长‘, ‘冯乡长‘, ‘刘能‘}
7 # 结果:>>> {‘赵四‘, ‘刘科长‘, ‘冯乡长‘, ‘刘能‘}
5)子集 - < - issubset # 包含于
1 # 子集——被包含
2 s1 = {"刘能", "赵四"}
3 s2 = {"刘能", "赵四", "???"}
4 print(s1 < s2) # set1是set2的?集吗? True
5 print(s1.issubset(s2))
6 # 结果:>>> True
7 # 结果:>>> True
6)超集 - > - issuperset #包含
1 # 超集——包含
2 s1 = {"刘能", "赵四"}
3 s2 = {"刘能", "赵四", "???"}
4 print(s2 > s1) # set1是set2的超集吗? False
5 print(s2.issuperset(s1))
6 # 结果:>>> True
7 # 结果:>>> True
三、深浅拷贝
1、赋值 “ = ”
(1)对于list ,set,dict 来说,直接赋值,其实就是把内存地址交给变量,并不是复制一份内容。所以,lst1的内存指向和lst2的内存指向是一样的。lst1改变了,lst2也发生了变化。
1 lst1 = ["??狮王", "紫衫?王", "?眉鹰王", "?翼蝠王"]
2 lst2 = lst1
3 print(lst1)
4 print(lst2)
5 lst1.append("杨逍") #只给lst1追加一个人元素
6 print(lst1)
7 print(lst2)
8
9 # 结果:>>> [‘??狮王‘, ‘紫衫?王‘, ‘?眉鹰王‘, ‘?翼蝠王‘]
10 # 结果:>>> [‘??狮王‘, ‘紫衫?王‘, ‘?眉鹰王‘, ‘?翼蝠王‘]
11 # 结果:>>> [‘??狮王‘, ‘紫衫?王‘, ‘?眉鹰王‘, ‘?翼蝠王‘, ‘杨逍‘]
12 # 结果:>>> [‘??狮王‘, ‘紫衫?王‘, ‘?眉鹰王‘, ‘?翼蝠王‘, ‘杨逍‘]
字典也一样
1 1 dic1 = {"id": 123, "name": "谢逊"}
2 2 dic2 = dic1
3 3 print(dic1)
4 4 print(dic2)
5 5 dic1[‘name‘] = "范瑶" # 只修改dic1的name
6 6 print(dic1)
7 7 print(dic2)
8 8
9 9 # 结果:>>> {‘id‘: 123, ‘name‘: ‘谢逊‘}
10 10 # 结果:>>> {‘id‘: 123, ‘name‘: ‘谢逊‘}
11 11 # 结果:>>> {‘id‘: 123, ‘name‘: ‘范瑶‘}
12 12 # 结果:>>> {‘id‘: 123, ‘name‘: ‘范瑶‘}
面试题:(深坑)
1 a = [1, 2]
2 a[1] = a
3 print(a[1])
4 # 结果:>>> [1, [...]]
5 # [...] 是死循环的体现,也就是说a[1]在不断的调用a,然而a还在不断的调用a[1],死循环。
2、浅拷贝 copy()
(1)浅拷贝,就是只拷贝第一层,不会拷贝第二层甚至更深层的内容,所以被称为浅拷贝。(也就是嵌套里边的依旧是执向。)
1)两个lst完全不一样,内存地址和内容也不一样。发现实现了内存的拷贝
1 lst1 = ["何炅", "杜海涛","周渝?"]
2 lst2 = lst1.copy()
3 lst1.append("李嘉诚")
4 print(lst1)
5 print(lst2)
6 print(id(lst1), id(lst2))
7
8 # 结果:>>> [‘何炅‘, ‘杜海涛‘, ‘周渝?‘, ‘李嘉诚‘]
9 # 结果:>>> [‘何炅‘, ‘杜海涛‘, ‘周渝?‘]
10 # 结果:>>> 52560960 52717888
2)嵌套的话就能发现,其实浅拷贝拷贝的是第一层次的内存地址,第二层嵌套的内容在第一层中依旧是地址指向。
1 lst1 = ["何炅", "杜海涛","周渝?", ["麻花藤", "?芸", "周笔畅"]]
2 lst2 = lst1.copy()
3 lst1[3].append("?敌是多磨寂寞")
4 print(lst1)
5 print(lst2)
6 print(id(lst1[3]), id(lst2[3]))
7
8 # 结果:>>> [‘何炅‘, ‘杜海涛‘, ‘周渝?‘, [‘麻花藤‘, ‘?芸‘, ‘周笔畅‘, ‘?敌是多磨寂寞‘]]
9 # 结果:>>> [‘何炅‘, ‘杜海涛‘, ‘周渝?‘, [‘麻花藤‘, ‘?芸‘, ‘周笔畅‘, ‘?敌是多磨寂寞‘]]
10 # 结果:>>> 57476160 57476160
3、深拷贝 .deepcopy()
(1)深度拷贝,会把元素内部的所有元素完全进行拷贝复制,就不会再产生一个改变另一个跟着改变的问题了。
(2)深拷贝需要先 import copr。
1 import copy
2 lst1 = ["何炅", "杜海涛","周渝民", ["麻花藤", "马芸", "周笔畅"]]
3 lst2 = copy.deepcopy(lst1)
4 lst1[3].append("?敌是多磨寂寞")
5 print(lst1)
6 print(lst2)
7 print(id(lst1[3]), id(lst2[3]))
8
9 # 结果:>>> [‘何炅‘, ‘杜海涛‘, ‘周渝民‘, [‘麻花藤‘, ‘马芸‘, ‘周笔畅‘, ‘?敌是多磨寂寞‘]]
10 # 结果:>>> [‘何炅‘, ‘杜海涛‘, ‘周渝民‘, [‘麻花藤‘, ‘马芸‘, ‘周笔畅‘]]
11 # 结果:>>> 53087448 53117136
标签:内存 直接 增删改 完成 李嘉诚 怎么办 sig remove index
原文地址:https://www.cnblogs.com/clbao/p/9305213.html