集合及深浅拷贝

集合(Set)是简单对象的无序集合(Collection)。当集合中的项目存在与否比起次序或其出现次数更加重要时,我们就会使用集合。
特点:1.数据无序,且不重复,故不支持索引,索引对于集合没有意义
          2.每个元素必须是不可变类型(可hash,可作为字典的key),当中不能插入字典或者列表,会报错
          
去重,把一个列表变成集合,就自动去重了。
关系测试,测试两组数据之前的交集、差集、并集等关系。
 
python符号
含义
差集,相对补集
&
交集
|
并集
!=
不等于
==
等于
in
是成员关系
not in
不是成员关系
 

3.1 集合的创建

set1 = set({1,2,'barry'})
set2 = {1,2,'barry'}
print(set1,set2)
---{1, 2, 'barry'} {1, 2, 'barry'}
bri = set(['brazil', 'russia', 'india'])
 'india' in bri
---True
'usa' in bri
---False
bric = bri.copy()
bric.add('china')
bric.issuperset(bri)
---True
bri.remove('russia')
bri & bric # OR bri.intersection(bric)
---{'brazil', 'india'}

3.2集合的增 

set1 = {'alex','wusir','ritian','egon','barry'}
set1.add('景女神')
print(set1)
---{'景女神', 'ritian', 'egon', 'barry', 'wusir', 'alex'}     #无序的增加进去

#连续性的添加元素进去
set1.update('A')
print(set1)
set1.update('老师')
print(set1)
set1.update([1,2,3])    #注意这行的列表元素添加进去,直接成集合的一部分了
print(set1)
---{'egon', 'A', 'ritian', 'alex', 'barry', 'wusir'}
---{'egon', 'A', '', '', 'ritian', 'alex', 'barry', 'wusir'}
---{'egon', 1, 2, 'A', '', 3, '', 'ritian', 'alex', 'barry', 'wusir'}    

 3.3集合的删

set1 = {'alex','wusir','ritian','egon','barry'}
set1.remove('alex')        # 删除一个元素print(set1)
set1.pop()           # 我去他大爷的,括号里面居然添加不了任何参数,只能随机删除掉一个元素,然后print(set1)
set1.clear()        # ,括号里面也无法添加元素,直接清空集合print(set1)
del set1                           # 删除集合print(set1)

3.4集合其他操作

3.4.1交集  (&  或者 intersection)
set1 = {1,2,3,4,5}
set2 = {4,5,6,7,8}
print(set1 & set2)   # {4, 5}
print(set1.intersection(set2))   # {4, 5}
3.4.2 并集。(| 或者 union)
3.4.3 差集。(- 或者 difference)   
set1 = {1,2,3,4,5}
set2 = {4,5,6,7,8}
print(set1 - set2)      # {1, 2, 3}
print(set1.difference(set2))      # {1, 2, 3}
3.4.4反交集。(^ 或者 symmetric_difference)   # 两个集合存在共性元素,打印两个集合中所有非共性元素
3.4.5子集与超集(返回的是布尔值)
set1 = {1,2,3}
set2 = {1,2,3,4,5,6}
print(set1 < set2)  #True
print(set1.issubset(set2))   #True        # 这两个相同,都是说明set1是set2子集。
print(set2 > set1)
print(set2.issuperset(set1))      # 这两个相同,都是说明set2是set1超集。

 3.5不可变集合的创建:

a = {'dsa', 'asf'}
b = frozenset(a)
print(b, type(b))
---frozenset({'dsa', 'asf'}) <class 'frozenset'>

3.6集合与内置函数间的关系

函数描述
all() 如果集合中的所有元素都是 True(或者集合为空),则返回 True。
any() 如果集合中的所有元素都是 True,则返回 True;如果集合为空,则返回 False。
enumerate() 返回一个枚举对象,其中包含了集合中所有元素的索引和值(配对)。
len() 返回集合的长度(元素个数)
max() 返回集合中的最大项
min() 返回集合中的最小项
sorted() 从集合中的元素返回新的排序列表(不排序集合本身)
sum() 返回集合的所有元素之和
 

总结:

方法描述
add() 将元素添加到集合中
clear() 删除集合中的所有元素
copy() 返回集合的浅拷贝
difference() 将两个或多个集合的差集作为一个新集合返回
difference_update() 从这个集合中删除另一个集合的所有元素
discard() 删除集合中的一个元素(如果元素不存在,则不执行任何操作)
intersection() 将两个集合的交集作为一个新集合返回
intersection_update() 用自己和另一个的交集来更新这个集合
isdisjoint() 如果两个集合有一个空交集,返回 True
issubset() 如果另一个集合包含这个集合,返回 True
issuperset() 如果这个集合包含另一个集合,返回 True
pop() 删除并返回任意的集合元素(如果集合为空,会引发 KeyError)
remove() 删除集合中的一个元素(如果元素不存在,会引发 KeyError)
symmetric_difference() 将两个集合的对称差作为一个新集合返回
symmetric_difference_update() 用自己和另一个的对称差来更新这个集合
union() 将集合的并集作为一个新集合返回
update() 用自己和另一个的并集来更新这个集合
 

3.7赋值运算 

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']]
对于赋值运算来说,l1与l2指向的是同一个内存地址,所以他们是完全一样的。

linuxs={'six','wu','dabao'}
linuxs.add('xiaoxiao')  #说明set类型的集合是可变类型
linuxs.add([1,2,3])  #报错,只能添加不可变类型
print(linuxs)

3.8浅拷贝copy (注意不同点)  -->详细解释猛戳这里

l1 = [1,2,3,['barry','alex']]
l2 = l1.copy()
print(l1,id(l1)) # [1, 2, 3, ['barry', 'alex']] 2380296895816
print(l2,id(l2)) # [1, 2, 3, ['barry', 'alex']] 2380296895048
l1[1] = 222
print(l1,id(l1)) # [1, 222, 3, ['barry', 'alex']] 2593038941128
print(l2,id(l2)) # [1, 2, 3, ['barry', 'alex']] 2593038941896
l1[3][0] = 'wusir'
print(l1,id(l1[3]))            # [1, 222, 3, ['wusir', 'alex']] 1732315659016          
print(l2,id(l2[3]))            # [1, 2, 3, ['wusir', 'alex']] 1732315659016
对于浅copy来说,第一层创建的是新的内存地址,而从第二层开始,指向的都是同一个内存地址,所以,对于第二层以及更深的层数来说,保持一致性(浅拷贝)。

3.9 深拷贝deepcopy

import copy
l1 = [1,2,3,['barry','alex']]
l2 = copy.deepcopy(l1)

print(l1,id(l1))      # [1, 2, 3, ['barry', 'alex']] 2915377167816
print(l2,id(l2))     # [1, 2, 3, ['barry', 'alex']] 2915377167048
l1[1] = 222
print(l1,id(l1))       # [1, 222, 3, ['barry', 'alex']] 2915377167816
print(l2,id(l2))      # [1, 2, 3, ['barry', 'alex']] 2915377167048
l1[3][0] = 'wusir'
print(l1,id(l1[3]))      # [1, 222, 3, ['wusir', 'alex']] 2915377167240
print(l2,id(l2[3]))      # [1, 2, 3, ['barry', 'alex']] 2915377167304
对于深copy来说,两个是完全独立的,改变任意一个的任何元素(无论多少层),另一个绝对不改变。

注:

对于数字和字符串而言,赋值、浅拷贝和深拷贝无意义,其永远指向同一个内存地址
对于字典、元祖、列表 而言,进行赋值、浅拷贝和深拷贝时,其内存地址的变化是不同的
原文地址:https://www.cnblogs.com/LearningOnline/p/8448566.html