Python基础(元祖,集合)
一,什么是元祖
- 元祖
- Python内置的数据结构之一,是一个不可变序列
不可变序列与可变序列
-
不可变序列:字符串、元祖
- 不可变序列特点:没有增、删、改的操作
-
可变序列:列表、字典
- 可变序列:可以对序列执行增、删、改操作,对象地址不发生更改
-
''' 可变序列,列表、字典 ''' lst=[10,20,30] print(id(lst)) lst.append(300) print(id(lst))
输出:
2332067655040
2332067655040
不可变序列,更改好id会变
'''
不可变序列
'''
s='hello'
print(id(s))
s=s+' world'
print(s)
print(id(s))
输出:
2528903130032
hello world
2528903142640
元祖示例
t = (‘Python’,‘hello’,90)
与列表的区别,列表是方括号 [] , 元祖是小括号 ()
二、元祖的创建方式
-
元祖的创建方式
-
直接小括号
-
''' 元祖的创建方式 ''' ''' 第一种,使用() ''' t= ('Python','hello','world',98) print(t) print(type(t))
-
-
使用内置函数:tuple()
''' 第二种:使用内置函数tuple() ''' t1=tuple(('hello0','world')) print(t1) print(type(t1))
-
元祖中只有一个元素的情况
-
只有一个元祖的情况,逗号不能省略
-
'''只包含一个元祖的元素需要使用逗号和小括号''' t=(10,) print(t) print(type(t)) t3=('hello',) print(t3) print(type(t3))
-
输出:
(10,) <class 'tuple'> ('hello',) <class 'tuple'>
-
-
-
空元祖的创建方式
t5=()
t6=tuple() -
'''空元祖的创建方式''' '''回顾空列表的创建方式''' lst=[] lst1 = list() '''空字典的创建方式''' d={} d2 = dict() #空元祖 t5=() t6=tuple() print(t5) print(t6)
输出:
() ()
三、为什么要将元祖设计成不可变序列
-
在多任务环境下,同时操作对象时不需加锁
-
因此,在程序中尽量使用不可变序列
-
注意事项:元祖中存储的是对象的引用
- 如果元祖中对象本身不可变对象,则不能再引用其他对象
- 如果元祖中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变
t=(10,[20,30],9) print(t) print(type(t)) print(t[0],type(t[0]),id(t[0])) print(t[1],type(t[1]),id(t[1])) print(t[2],type(t[2]),id(t[2]))
输出:
(10, [20, 30], 9) <class 'tuple'> 10 <class 'int'> 2297849932368 [20, 30] <class 'list'> 2297858149888 9 <class 'int'> 2297849932336 2297850123728
t[1] 的元素是可变序列
当试图修改这个列表时:
print(id(100)) t[1]=100
报错
t[1]=100 TypeError: 'tuple' object does not support item assignment
因为这样改会修改元祖里面存储的对象的引用地址
如果只是修改这个可变列表的内容而不是修改这个可变列表本身,则可以
t[1].append(300) print(t)
输出:
(10, [20, 30, 300], 9)
四、元祖的遍历
第一种:使用索引
'''
元祖的遍历
'''
t=('Python','world',98)
'''第一种获取元祖元素的方式,使用索引'''
print(t[0])
print(t[1])
print(t[2])
输出:
Python
world
98
第二种:for…in…
'''第二种, for...in...遍历'''
t=('Python1','world1',981)
for item in t:
print(item)
输出:
Python1
world1
981
集合
一、什么是集合
- 集合
- Python语言提供的内置数据结构
- 与列表、字典一样都属于可变类型的序列
- 集合是没有value的字典
二、集合的创建方式
-
第一种:直接{}
- s={‘Python’,‘hello’, 90}
s1={1,2,2,3,4,5,5,8} print(s1)
输出:
{1, 2, 3, 4, 5, 8}
结论:集合中元素不能重复
-
第二种:使用内置函数set()
s=set(range(6)) #直接从0到5的int数集合 print(s) print(set([3,4,5,7])) #将列表类型转成集合类型 print(set((5,6,7,8))) #将元祖类型转换成集合类型 print(set('Python')) #将字符串类型转成集合类型 print(set({124,3,5,6})) #当然也包括集合类型,但是顺序会变 print(set())
输出:
{0, 1, 2, 3, 4, 5}
{3, 4, 5, 7}
{8, 5, 6, 7}
{'t', 'y', 'n', 'o', 'P', 'h'}
{3, 124, 5, 6}
set()
再刷一次:
{0, 1, 2, 3, 4, 5}
{3, 4, 5, 7}
{8, 5, 6, 7}
{'o', 'y', 'h', 'n', 'P', 't'}
{3, 124, 5, 6}
set()
字符串类型的转成集合,变成单个字符的集合,顺序是随机的,每次都不一样
定义一个空集合
-
print('----定义一个空集合----') s6={} print(type(s6)) s7 = set() print(type(s7))
输出:
----定义一个空集合----
<class 'dict'>
<class 'set'>
定义一个空集合不能用单独用{},必须用set()
三、集合元素的相关操作
集合元素的判断操作
-
in 或 not in
'''集合元素的判断操作''' s = {10,20,30,405,60} print(10 in s) #True print(100 in s) #False print(10 not in s) #False print(100 not in s) #True
集合元素的新增操作
- add()一次添加一个
s = {10,20,30,405,60}
s.add(80)
print(s)
输出:
-----集合元素的新增操作-----
{80, 20, 405, 10, 60, 30}
当 add()添加两个时,如:
报错: s.add(29,31)
TypeError: set.add() takes exactly one argument (2 given)
add() 只能一次添加一个
如何同时添加多个?
-
update()
里面可以添加个列表:
print('-----集合元素的新增操作-----') s = {10,20,30,405,60} s.add(80) print(s) s.update([22,26,55]) print(s)
输出:
-----集合元素的新增操作----- {80, 20, 405, 10, 60, 30} {10, 80, 20, 405, 22, 26, 30, 55, 60}
-
还可以添加元祖
print('-----集合元素的新增操作-----') s = {10,20,30,405,60} s.add(80) print(s) s.update([22,26,55]) print(s) s.update({88,90,92}) print(s)
输出:
-----集合元素的新增操作----- {80, 20, 405, 10, 60, 30} {10, 80, 20, 405, 22, 26, 30, 55, 60} {10, 80, 20, 405, 22, 88, 26, 90, 92, 30, 55, 60}
可以看到,里面顺序不是按照添加的次序来的
-
集合元素的删除操作
- 调用remove()方法,一次删除一个指定元素,如果指定的元素不存在抛出KeyError
print('-----集合元素的删除操作----')
s={10,20,30,40,50,60,70,80}
print(s)
s.remove(80)
print(s)
输出:
-----集合元素的删除操作----
{70, 40, 10, 80, 50, 20, 60, 30}
{70, 40, 10, 50, 20, 60, 30}
删除了80这个元素
假如去删除90,这个集合中没有的元素
print('-----集合元素的删除操作----')
s={10,20,30,40,50,60,70,80}
print(s)
s.remove(90)
print(s)
报错:
s.remove(90)
KeyError: 90
- 调用discard()方法,一次删除一个指定元素,如果指定的元素不存在不抛出异常
print('-----集合元素的删除操作discard()----')
s={10,20,30,40,50,60,70,80}
print(s)
s.discard(10)
print(s)
输出:
-----集合元素的删除操作discard()----
{70, 40, 10, 80, 50, 20, 60, 30}
{70, 40, 80, 50, 20, 60, 30}
假如删除一个没有的元素
print('-----集合元素的删除操作discard()----')
s={10,20,30,40,50,60,70,80}
print(s)
s.discard(15)
print(s)
结果:没有报错
-----集合元素的删除操作discard()----
{70, 40, 10, 80, 50, 20, 60, 30}
{70, 40, 10, 80, 50, 20, 60, 30}
没有删除元素
- 调用pop()方法,一次只删除一个任意元素
print('-----集合元素的删除操作pop()-----')
s={22,32,42,52,62,72,82}
print(s)
s.pop()
print(s)
输出:
-----集合元素的删除操作pop()-----
{32, 82, 52, 22, 72, 42, 62}
{82, 52, 22, 72, 42, 62}
删除了32,这个元素
- 调用clear()方法,清空集合
print('-----集合元素的删除操作pop()-----')
s={22,32,42,52,62,72,82}
print(s)
s.clear()
print(s)
输出:
-----集合元素的删除操作pop()-----
{32, 82, 52, 22, 72, 42, 62}
set()
四、集合间的关系
两个集合是否相等
- 可以使用运算符 == 或者 != 进行判断
print('-----集合间的关系-----')
s={10,20,30,40,50}
s2={30,20,40,10,50}
print(s==s2)
print(s!=s2)
输出:
-----集合间的关系-----
True
False
顺序不一样没关系,因为集合里的元素本来就没有顺序
一个集合是否是另一个集合的子集
- issubset() 进行判断
print('-----一个集合是否是另一个集合的子集-----')
s={10,20,30,40,50,60,70,80}
s1={10,20,50,60}
s2={10,30,90}
print(s1.issubset(s))
print(s2.issubset(s))
输出:
-----一个集合是否是另一个集合的子集-----
True
False
一个集合是否是另一个集合的超集
- issuperset进行判断
print('-----一个集合是否是另一个集合的超集-----')
s={10,20,30}
s1={10,20,30,40}
s2={10,20,60}
print(s1.issuperset(s))
print(s2.issuperset(s))
输出:
-----一个集合是否是另一个集合的子集-----
True
False
两个集合是否没有交集
isdisjoint()
print('-----两个集合是否没有交集-----')
s1={12,22,32,42,52}
s2={12,22,33}
s3={62,61,66}
print(s1.isdisjoint(s2))
print(s3.isdisjoint(s1))
输出:
-----两个集合是否没有交集-----
False
True
五、集合的数学操作
交集
intersection() 与 &
print('-----两个集合的交集-----')
s1={10,20,30,40}
s2={20,30,40,50}
print('s1和s2的交集:',s1.intersection(s2))
print(s1 & s2) #intersection() 等价于 &
输出:
-----两个集合的交集-----
s1和s2的交集: {40, 20, 30}
{40, 20, 30}
并集
union() 与 |
print('-----两个集合的并集-----')
s1={10,20,30,40}
s2={20,30,40,50}
print('s1和s2的并集:',s1.union(s2))
print(s1 | s2) #intersection() 等价于 |
输出:
-----两个集合的并集-----
s1和s2的并集: {40, 10, 50, 20, 30}
{40, 10, 50, 20, 30}
差集
用 difference() 或者 - 减号
print('-----两个集合的差集-----')
s1={10,20,30,40}
s2={20,30,40,50}
print('s1和s2的差集:', s1.difference(s2))
print('s1和s2的差集:', s2.difference(s1))
print('s1和s2的差集:', s1-s2)
print('s2和s1的差集:', s2-s1)
输出:
-----两个集合的差集-----
s1和s2的差集: {10}
s1和s2的差集: {50}
s1和s2的差集: {10}
s2和s1的差集: {50}
对称差集
symmetric_difference() 或者 ^
print('-----两个集合的对称差集-----')
s1={10,20,30,40}
s2={20,30,40,50}
print('s1和s2的对称差集:', s1.symmetric_difference(s2))
print('s1和s2的对称差集:', s1^ s2)
输出:
-----两个集合的对称差集-----
s1和s2的对称差集: {10, 50}
s1和s2的对称差集: {10, 50}
集合生成式
- 用于生成集合的公式
{ i * i for i in range(1,10)}
i*i 表示集合元素的表达式
i 自定义变量
range(1,10) 可迭代对象
-
将{} 改为[]就是列表生成式
-
没有元祖生成式 (元祖不可变)
print('-----集合生成式-----')
set1 = {i*i for i in range(1,10)}
print(set1)
set2 = {i*(i-1) for i in range(1,10)}
print(set2)
输出:
-----集合生成式-----
{64, 1, 4, 36, 9, 16, 49, 81, 25}
{0, 2, 6, 72, 42, 12, 20, 56, 30}
列表、字典、元祖、集合总结
数据结构 | 是否可变 | 是否重复 | 是否有序 | 定义符号 |
---|---|---|---|---|
列表(list) | 可变 | 可重复 | 有序 | [] |
元祖(tuple) | 不可变 | 可重复 | 有序 | () |
字典(dict) | 可变 | key不可重复value可重复 | 无序 | {key:value} |
集合(set) | 可变 | 不可重复 | 无序 | {} |