集合(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集合与内置函数间的关系
|
总结:
|
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来说,两个是完全独立的,改变任意一个的任何元素(无论多少层),另一个绝对不改变。
注:
对于数字和字符串而言,赋值、浅拷贝和深拷贝无意义,其永远指向同一个内存地址
对于字典、元祖、列表 而言,进行赋值、浅拷贝和深拷贝时,其内存地址的变化是不同的