主要内容
- 1.set集合
- 2.深浅拷贝
1.set集合
1.1 set集合相关概述
- set集合是python的一个基本数据类型
- set中的元素是不重复的,无序的,里面的元素必须是可hash的 (int, str, tuple,bool)
- set就是dict类型的数据但是不保存value, 只保存key. set也用{}表示
- 另外:set集合中的元素必须是可哈希的,但是set本身不可hash,set是可变的
set1 = {'1','alex',2,True,[1,2,3]} # 报错
set2 = {'1','alex',2,True,{1:2}} # 报错
set3 = {'1','alex',2,True,(1,2,[2,3,4])} # 报错 -
set中元素不重复,且是无序的
s = {"周杰伦", "周杰伦", "周星星"} print(s) #结果: {'周星星', '周杰伦'}
-
利用集合的特点可以将list元素去重 list(set(lst)) # 去重复
lst = [1,2,3,4,4,4,4,5,5,6,7,7,7] s = set(lst) lst = list(s) print(lst) #[1, 2, 3, 4, 5, 6, 7]
1.2 集合de增删改查
- 增加
s = {"刘嘉玲", '关之琳', "王祖贤"} s.add("郑裕玲") print(s) s.add("郑裕玲") # 重复的内容不会被添加到set集合中 print(s) s = {"刘嘉玲", '关之琳', "王祖贤"} s.update("麻花藤") # 迭代更新 print(s) s.update(["张曼玉", "李若彤","李若彤"]) print(s)
- 删除
s = {"刘嘉玲", '关之琳', "王祖贤","张曼玉", "李若彤"} item = s.pop() # 随机弹出⼀一个. print(s) print(item) s.remove("关之琳") # 直接删除元素 # s.remove("马虎疼") # 不存在这个元素. 删除会报错 print(s) s.clear() # 清空set集合.需要注意的是set集合如果是空的. 打印出来是set() 因为要和 dict区分的. print(s) # set()
- 修改
# set集合中的数据没有索引. 也没有办法去定位⼀一个元素. 所以没有办法进⾏行行直接修改. # 我们可以采⽤用先删除后添加的⽅方式来完成修改操作 s = {"刘嘉玲", '关之琳', "王祖贤","张曼玉", "李若彤"} # 把刘嘉玲改成赵本山 s.remove("刘嘉玲") s.add("赵本山") print(s)
- 查询
# set是⼀一个可迭代对象 所以可以进行for循环 for el in s: print(el)
1.3 集合常用操作
- 交集
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)) # {'冯乡长', '刘能', '刘科长', '赵四'}
- 子集
print(s1 < s2) # set1是set2的子集吗? True print(s1.issubset(s2)
- fronzenset set集合本身是可以发生改变的. 是不可hash的,我们可以使用frozenset来保存数据. frozenset是不可变的. 也就是⼀个可哈希的数据类型
s = frozenset(["赵本山", "刘能", "皮长山", "长跪"]) dic = {s:'123'} # 可以正常使用了 print(dic)
2.深浅拷贝
2.1 赋值运算 :
- 赋值没有创建新对象,多个变量共享同一个对象
l1 = [1,2,3,['barry','alex']] l2 = l1 l1[0] = 111 print(l1) # [111, 2, 3, ['barry', 'alex']] print(l2) # [111, 2, 3, ['barry', 'alex']] l1[3][0] = 'wusir' print(l1) # [111, 2, 3, ['wusir', 'alex']] print(l2) # [111, 2, 3, ['wusir', 'alex']]
2.2 浅拷贝 :增加了一个指针指向一个存在的内存地址
- 两种方式
lst1 = ["太白","日天","哪吒","银角大王","金角大王"] lst2 = lst1 lst1.append("女神") print(lst1,id(lst1)) # ['太白', '日天', '哪吒', '银角大王', '金角大王', '女神'] 2420170040264 print(lst2,id(lst2)) #['太白', '日天', '哪吒', '银角大王', '金角大王', '女神'] 2420170040264 #指向同一个内存地址,所以二者相同
lst1 = ["太白","日天","哪吒","银角大王","金角大王"] lst2 = lst1.copy() # 会创建新对象, 创建对象的速度会很快. lst2 = lst1[:] 创建了新列表 lst1.append("女神") print(lst1,id(lst1)) #['太白', '日天', '哪吒', '银角大王', '金角大王', '女神'] 2606709613704 print(lst2,id(lst2)) #['太白', '日天', '哪吒', '银角大王', '金角大王'] 2606709613832
- 多层情形
lst1 = ["太白","日天",["盖浇饭", "锅包肉", "吱吱冒油的猪蹄子"],"哪吒","银角大王","金角大王"] lst2 = lst1.copy() # 会创建新对象, 创建对象的速度会很快. lst1[2].append("油泼扯面") print(lst1, id(lst1[2])) #['太白', '日天', ['盖浇饭', '锅包肉', '吱吱冒油的猪蹄子', '油泼扯面'], '哪吒', '银角大王', '金角大王'] 1440371189000 print(lst2, id(lst2[2])) #['太白', '日天', ['盖浇饭', '锅包肉', '吱吱冒油的猪蹄子', '油泼扯面'], '哪吒', '银角大王', '金角大王'] 1440371189000
浅拷贝. 只会拷贝第⼀层. 第二层的内容不会拷贝. 所以被称为浅拷贝
2.3 深拷贝 增加一个指针并且开辟了新的内存,这个增加的指针指向这个新的内存
- 单层
import copy li1 = [1, 2, 3] li2 = copy.deepcopy(li1) li1.append(4) print(li1, id(li1)) # [1, 2, 3, 4] 3112618579592 print(li2, id(li2)) # [1, 2, 3] 3112618579784
- 多层
import copy li1 = [1, 2, 3,[4,5],6] li2 = copy.deepcopy(li1) li1[3].append(7) print(li1, id(li1)) # [1, 2, 3, [4, 5, 7], 6] 2575562397512 print(li2, id(li2)) # [1, 2, 3, [4, 5], 6] 2575562398792
注:深拷贝. 把元素内部的元素完全进行拷贝复制.,不会产生一个改变另一个跟着改变的问题
一个面试题:
a = [1, 2] a[1] = a print(a[1])