python 学习笔记5(深浅拷贝与集合)
拷贝
我们已经详细了解了变量赋值的过程。对于复杂的数据结构来说,赋值就等于完全共享了资源,一个值的改变会完全被另一个值共享。
然而有的时候,我们偏偏需要将一份数据的原始内容保留一份,再去处理数据,这个时候使用赋值就不够明智了。python为这种需求提供了copy模块。提供了两种主要的copy方法,一种是普通的copy,另一种是deepcopy。我们称前者是浅拷贝,后者为深拷贝。
深浅拷贝一直是所有编程语言的重要知识点,下面我们就从内存的角度来分析一下两者的区别。
浅拷贝
首先,我们来了解一下浅拷贝。浅拷贝:不管多么复杂的数据结构,浅拷贝都只会copy一层。
#浅拷贝 a = [[1,2],3,4] b = a.copy() b[2] = 5 b[0][0] = 7 print(a,b)
深拷贝
刚刚我们了解了浅拷贝的意义,但是在写程序的时候,我们就是希望复杂的数据结构之间完全copy一份并且它们之间又没有一毛钱关系,应该怎么办呢?
我们引入一个深拷贝的概念,深拷贝——即python的copy模块提供的另一个deepcopy方法。深拷贝会完全复制原变量相关的所有数据,在内存中生成一套完全一样的内容,在这个过程中我们对这两个变量中的一个进行任意修改都不会影响其他变量。
#深拷贝 import copy a = [[1,2],3,4] b=copy.deepcopy(a) b[1] = 5 b[0][1] = 7 print(a,b)
深拷贝就是在内存中重新开辟一块空间,不管数据结构多么复杂,只要遇到可能发生改变的数据类型,就重新开辟一块内存空间把内容复制下来,直到最后一层,不再有复杂的数据类型,就保持其原引用。这样,不管数据结构多么的复杂,数据之间的修改都不会相互影响。这就是深拷贝。
深浅拷贝修改前后的关系图
集合
集合(set):把不同的元素组成一起形成集合,是python基本的数据类型。
集合的作用:去重 和 关系测试
集合元素(set elements):组成集合的成员
集合对象是一组无序排列的可哈希的值:集合成员可以做字典的键
集合分类:可变集合、不可变集合
可变集合(set):可添加和删除元素,非可哈希的,需要的元素为可哈希的,不能用作字典的键,也不能做其他集合的元素
不可变集合(frozenset):与可变集合相反
集合操作符与关系符号:
集合的创建
a = set([1,2,3,4,5]) b = set([3,4,5,6,7])
a = set("liu")
b = set(a)
访问集合
可用for循环遍历,也可用迭代器,in 和not in
#遍历输出 for i in a: print(i) #判断在不在集合里print(1 in a)print(1 not in a)
更新集合
1.增加
#增加a.add("lll")a.add("lllq")a.add([1,3]) #unhashable type: 'list'a.update("ide") #{1, 2, 3, 4, 5, 'd', 'i', 'e'}a.update([12,"tgh"]) #{'tgh', 1, 2, 3, 4, 5, 12}
2.删除
#删除 a.remove(1) #{2, 3, 4, 5} a.pop() # 随机删除 {2, 3, 4, 5} a.clear() #set() del a #NameError: name 'a' is not defined print(a)
集合的操作
#关系测试
1. in not in
2.等价 == 不等价 !=
print(a == b) #False
print(a != b) #True #交集
print(a.intersection(b)) #{3, 4, 5}
print(a&b)
#并集
print(a.union(b)) #{1, 2, 3, 4, 5, 6, 7}
print(a | b)
#差集
print(a.difference(b)) #{1, 2}
print(a-b)
print(b.difference(a)) #{6, 7}
print(b-a) #对称差集(反向交集)
print(a.symmetric_difference(b)) #{1, 2, 6, 7}
print(a^b) #超集(父级)
print(a.issuperset(b)) #False
print(a>b) #子集 print(a.issubset(b)) #False print(a<b)