元组和列表很像,同样我们可以用它来放一些数据,但是不同的是,将数据放进元组这样的容器中后,就不能再对里面的元素作修改了,所谓的修改也就是增、删、改了,那么,相信你也产生了这样的疑惑:这样“不方便的数据类型”有什么用呢?这是每一个初学者都会产生的问题。
是的,元组确实是很少被使用,但是这并不代表它没有用,如果仅是单单认为它就是一个不可变的列表的话,可能就忽略了它真正存在的意义,这样要是在面试被问到的话,你很可能会一脸懵逼。实际上,元组之所以存在,也是因为它的不可变性这个特点,想像一下,如果你创建了一条记录,将它给其他人浏览,那你肯定不希望被人修改它原始的样子吧,特别是名字、性别、籍贯等这样重要的信息,要是将它放到列表,那么这样的数据是不具有保护性的,也就是因为这样,为了满足这样的需求,因此,产生了列表这样的容器型数据类型,通常将它来作为记录工具来使用,而第二个身份才是一个不可变的列表,也是因为它本身并不支持更改,因此,能对它所做的操作也是很少。
下面来看看它的定义方法以及操作等
元组采用()
将元素包起来,括号里面可以放的元素数据类型和列表一样,基本上所有类型的数据都可以放,例如下面这样
定义一个空元组
a = ()
定义一个一元组(这里有一个坑)
如果你这样定义一个只有一个元素,我们将就看一下它的数据类型
b = (3) print(type(b)) # 它的返回结果是<class 'int'>
为什么是这样呢?大家还记得()还可以做什么吗?它是不是在运算时提升括号里面的数据的元素优先级,那么在这里,如果你这样定义,那它就相当于你是给里面的 3 提升了优先级,并不知道你想定义一个元组,那么该怎样做呢?
b = (3,) print(type(b)) # 它的返回结果是<class 'tuple'>
所以,定义一个只有一个元素的元组就一定要在写了元素后加一个逗号(英文输入法下)
定义一个二元组
c = (1,2)
定义一个三元组
d = ('hello',2,3)
采用构造器语法也能创建一个元组,但是并不推荐,坑太多,所以这里就不举例了。定义好一个元组后,我们来看看能对它做哪些操作。
查看变量的类型type()、 查看元组中元素的数量len()、循环遍历元组中的元素、成员运算(元素在不在某个元组里)、切片、等和列表的操作大同小异,我就不一一举例,还不明白的请看我之前写的《5分钟带你了解Python中的容器型数据类型–列表2》,这里我们主要看一下它和列表的不同之处。
在相对列表进行某个元素的更改时,往往我们先将这个元素通过索引拿到,然后再进行赋值操作,这样就可以将这个元素更改成新赋的值,但是,在元组里面进行这样的操作我们可以看一下。
当你这样操作时它就已经标出了颜色(pycham环境),如果你硬是要运行,会得到下面这样一个报错:
TypeError: ‘tuple’ object does not support item assignment(类型错误:元组对象不支持赋值操作)
如果你是纯取出来,那样是可以的。总的来说,只要你不尝试更改它,其他操作基本和列表都是一样的
主要就是讲这一点注意事项。其他操作我就不再赘述,大家借用列表的知识去尝试练习,会事半功倍哦
打包和解包:
当我们给一个变量赋多个值时,这时候系统会将这些值打包
成一个元组,例如
a = 2, 0, 2, 1 print(type(a), a) # 输出<class 'tuple'> (2, 0, 2, 1)
什么又是解包呢?大家在python中想对两个变量进行值得交换时并不需要像在其它语言上那样定义一个临时变量作为交换的临时存储工具,如果想对a,b两个变量的值进行交换,只需要这样做
a = 1 b = 2 a, b = b, a print(a,b) # 输出 2 1
其实这样的操作就是一个解包
的过程,
解包就是在给多个变量同时赋值的时候,这时候右边就是一个元组,将元组里的值赋给对应的变量的过程,这里的a, b = b, a的右边就是一个二元组,再将对应的b的值赋给a,将a的值赋给了b,就实现了变量值的交换。但是对于解包时变量个数和元组的元素个数不等的情况,会引发valueError异常。例如:
a = 2, 0, 2, 1 i, k, h , l ,o = a #ValueError: not enough values to unpack (expected 5, got 4)(元组中的元素太少) y, z, w = a #ValueError: too many values to unpack (expected 3)(元组中的元素太多)
现在我们来思考一下函数中的可变参数(还不知道函数的请先跳过),参数之所以可变就是将多个参数打包成了一个元组,在传入参数时这时候实际上给函数传入的是一个元组,在对这个元组进行遍历就可以得到多个参数,例如:
def add(*args): print(type(args), args) add(1,2,5) # <class 'tuple'> (1, 2, 5) add(2,7,8,9) # <class 'tuple'> (2, 7, 8, 9)
下面我们来看一看另一种数据类型–集合。
说到集合,相信大家更是不陌生了吧,高中数学就学到了集合这个概念,具体概念我就不找官方定义放这里了,懂的都懂,至于不懂的嘛。嗯。。问问度娘。实际上,在python中的集合和数学上的集合可以说是一样的,通常这样定义它:把一定范围的、确定的、可以区别的事物当作一个整体来看待*,而对于它最重要的也是区分它和其他事物的根据是这样三个特征:
基于这样三个特征,我们可以知道,集合中的元素数不可以重复的(可以用这一点实现对其他容器类型的去重),集合中的元素是没有顺序的(因此不可以索引和切片),集合中的元素一定是确定的。python的集合同样采用{}
来表示
变量名 = {+元素} +号表示元素可以是1个或多个元素,这里并不是说不可以不放元素,而说如要定义一个空集合不能用这个语法
例如:
set1 = {5,1,5,90,2,2,2,3,} # 里面的元素可以为任何不可变类型,比如列表不能放(可变类型) print(set1) # {1, 2, 3, 5, 90}
而定义一个空集合为什么不能是set2 = {}呢?我们可以先试一下
set2 = {} print(type(set2)) # <class 'dict'>
得到的数据类型是dict(字典),也就是说,下面我们要介绍的另一种容器–字典也是用它{}来标识,所以说如果像上面这样定义一个空集合set2 = {},实际上得到的是一个空字典
。那么,只能退而求其次,定义一个空集合时请采用构造器语法
set2 = set() # 采用构造器语法创建 print(type(set2)) # <class 'set'>
不知道大家注意没有,定义set1时我写了这样一句注释“里面的元素可以为任何不可变类型,比如列表不能放(可变类型)
”,这里涉及到集合元素的存储方式(哈希存储)以及确定性的问题,感兴趣的自己百度一下,集合中是不能装可变数据类型的,集合本身也是可变类型,于是,如列表、集合、字典都是不能够放进集合中作为集合的元素的。如果硬要这么做,请看
set1 = {[2]} # 集合中放列表 set2 = {{3}} # 集合中放集合 set3 = {{'name':'王大锤'}} # 集合中放字典表 print(set1) # TypeError: unhashable type: 'list' print(set2) # TypeError: unhashable type: 'set' print(set3) # TypeError: unhashable type: 'dict
如数学上的集合相同,集合可以进行交并差、子集、超集运算等,不仅如此,还可以进行成员运算、相等性运算等
set1 = {1,23,45,6,7} set2 = {1,6,7} print(set2 & set1) # {1, 6, 7} # 或者使用intersection方法 print(set1.intersection(set2)) # {1, 6, 7}
set1 = {1,23,45,6,7} set2 = {1,6,7} print(set2 | set1) # {1, 6, 7, 45, 23} # 或者使用union方法 print(set1.union(set2)) # {1, 23, 6, 7, 45}
set1 = {1,23,45,6,7} set2 = {1,6,7} print(set1 - set2) # {45, 23} # 或者使用difference方法 print(set1.difference(set2)) # {45, 23}
set1 = {1,23,45,6,7} set2 = {1,6,7} print(set1 ^ set2) # {45, 23} # 或者使用symmetric_difference方法 print(set1.symmetric_difference(set2)) # {45, 23}
成员运算、比较运算(相等性、子集、超集等)和列表的成员运算、比较运算大同小异,这里不再赘述
集合除了交并差那些可调用的方法外,由于集合是一个可变的数据类型,所以,我们可以对它作元素的添加或删除操作等,下面我们看一下集合的常用方法。
set1 = {1,23,45,6,7} set1.add(5) print(set1) # {1, 5, 6, 7, 45, 23}
set1 = {1,23,45,6,7} set1.remove(6) # 注意,使用remove方法删除元素时,若元素不在集合中,会报错,所以删除前请先用成员运算判断该元素 print(set1) # {1, 7, 45, 23}
–采用discard
如果不想先进行成员运算,可用discard方法
set1 = {1,23,45,6,7} set1.discard(5) # 该元素不存在时不做修改也不报错 print(set1) # {1, 6, 7, 45, 23}
若只想随机删除一个元素,用pop方法
set1 = {1,23,45,6,7} set1.pop() # 不需要传入参数,因为集合无序,所以随机删掉一个元素 print(set1) # {6, 7, 45, 23}这里删掉了1
set1 = {1,23,45,6,7} set1.clear() print(set1) # set()
这些就是比较常用的集合的方法。集合先讲到这儿,接下来,我们看一下字典。
顾名思义,如新华字典、英汉字典、康熙字典等等,像这样
python里面的字典
dict1 = {'姓名':'张三','性别':'男','学历':'本科','生日':'1997-8-7','职业':'数据分析师','爱好':{'跑步':'马拉松','追剧':'韩剧'}}
这样可能没有对比性,看看这样
dict1 = {'姓名':'张三', '性别':'男', '学历':'本科', '生日':'1997-8-7', '职业':'数据分析师', '爱好':{'跑步':'马拉松','追剧':'韩剧'}}
这样是不是和现实中的字典很相似呢?都是前面有一个关键词,后面是对应的解释,在Python中的字典中,每一个元素是一个键值对
,“关键词或相应标识符 :对应存储的数据 ”这样就叫作一个键值对,比如
‘姓名’:‘张三’,前面的姓名叫做键
(key),后面的张三叫作值
(value),
那么定义一个这样的字典有什么用呢?查询吗?这样说也并没有错,的确,用字典来保存数据,对比之前所有的数据类型去保存以上那样的数据,是不是都更合适,因为这样做能让人对想了解的数据一目了然。当然了,它的功能不仅仅是保存数据,它的用处可大了,下面,我们分块来看看它的定义、操作、以及方法和实例。
语法也很简单:
变量名 = {元素} # 元素格式 key:value
元素的key是不可变数据类型
,是唯一的,就是说,在一个字典里面,键key每个元素不可以重复,而值value是可以重复的,而字典的键和集合的元素一样采用哈希存储,所以,字典的键key同样不能是列表、字典这样的可变数据类型(字典本身可变,它的键key不可变)
创建一个空字典
dict2 = {} print(type(dict2)) # <class 'dict'>
创建一个简单的字典
person = { 'name': '李白', 'age': 45, 'weight': 70, 'office': '四川成都高新区', 'home': '永丰街道39号', 'tel': '18888688458', 'QQ': '1690178545' }
person = dict(name='李白', age=45, weight=70, office= '四川成都高新区', home='永丰街道39号', tel='18888688458', QQ='1690178545',) print(person)
如列表一样,字典可以采用生成式(推导式)语法来创建,例如
nums_dict = {i:i**2 for i in range(10)} print(nums_dict) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
使用for循环,我们可以取到字典的每一个元素的键
dict1 = {'姓名':'张三','性别':'男','学历':'本科','生日':'1997-8-7', '职业':'数据分析师','爱好':{'跑步':'马拉松','追剧':'韩剧'}} for key in dict1: print(key) """ 输出结果: 姓名 性别 学历 生日 职业 爱好
这样只能够拿到字典的键,那怎样拿到它的值value呢?
索引,对,还是索引
这里主要介绍字典的成员运算和索引运算
索引
我们想拿到字典的值value,首先得先找到对应的键key,所以,在索引时,是通过字典的键来索引的,例如:
dict1 = {'姓名':'张三','性别':'男','学历':'本科','生日':'1997-8-7', '职业':'数据分析师','爱好':{'跑步':'马拉松','追剧':'韩剧'}} print(dict1['学历']) # 本科
这样就拿到了该键对应的值,值得注意的是,如果你索引的键不在字典中,将引发keyError异常
那么同样就可以采用先成员运算在索引来避免这样的麻烦。
成员运算
例如
person = dict(name='李白', age=45, weight=70, office= '四川成都高新区', home='永丰街道39号', tel='18888688458', QQ='1690178545',) print('住址' in person) # False print('QQ' not in person) # False
如果你索引的键不在字典中,将引发keyError异常,所以采用字典的方法get,也能拿到指定key所对应的值,而且解决了上面索引所以到的麻烦,这里,如果用get去取,如果取不到,会返回None或者你所设定的默认值。
person = dict(name='李白', age=45, weight=70, office= '四川成都高新区', home='永丰街道39号', tel='18888688458', QQ='1690178545',) print(person.get('住址')) # 没有取到返回None print(person.get('住址', '长江路7号')) # 没有取到返回指定的默认值长江路7号
使用索引或者get的方式一次只能拿到一个值,如果一次想拿全部的值,那样还要循环遍历是不是太难了,所以,python中有写好的方法去解决这样的问题。
person = dict(name='李白', age=45, weight=70, office= '四川成都高新区', home='永丰街道39号', tel='18888688458', QQ='1690178545',) print(person.values()) # dict_values(['李白', 45, 70, '四川成都高新区', '永丰街道39号', '18888688458', '1690178545'])
同样,不需要遍历,我们可以一次取到字典的键key
person = dict(name='李白', age=45, weight=70, office= '四川成都高新区', home='永丰街道39号', tel='18888688458', QQ='1690178545',) print(person.keys()) # dict_keys(['name', 'age', 'weight', 'office', 'home', 'tel', 'QQ'])
还有一个方法,既可以得到字典的键,也可以得到它的值
person = dict(name='李白', age=45, weight=70, office= '四川成都高新区', home='永丰街道39号', tel='18888688458', QQ='1690178545',) print(person.items()) # dict_items([('name', '李白'), ('age', 45), ('weight', 70), ('office', '四川成都高新区'), ('home', '永丰街道39号'), ('tel', '18888688458'), ('QQ', '1690178545')])
为了一次从这些键值对中同时既取出键,也取出值,对它作一个for循环遍历
for key, value in person.items(): print(key, '--->', value) """ name ---> 李白 age ---> 45 weight ---> 70 office ---> 四川成都高新区 home ---> 永丰街道39号 tel ---> 18888688458 QQ ---> 1690178545 """
删除键值对,有以下三种方法,三种方法略有不同,它们如要删除的键不存在,会引发keyError异常
person = dict(name='李白', age=45, weight=70) print(person.pop('name')) # 李白 #print(person.pop('QQ')) # KeyError: 'QQ' print(person) # {'age': 45, 'weight': 70}
person = dict(name='李白', age=45, weight=70) print(person.popitem()) # ('weight', 70) print(person) # {'name': '李白', 'age': 45}
person = dict(name='李白', age=45, weight=70) del person['age'] print(person) # {'name': '李白', 'weight': 70}
更新键值对
所要添加的这个键在字典中已经存在,不添加,返回对于应的值
所要添加的这个键在字典中不存在,添加进去,返回添加进去的值
dict1 = {'姓名':'张三','性别':'男','学历':'本科','生日':'1997-8-7',} print(dict1.setdefault('学历','研究生')) # 本科 print(dict1.setdefault('住址','长江路7号')) # 长江路7号 print(dict1) # {'姓名': '张三', '性别': '男', '学历': '本科', '生日': '1997-8-7', '住址': '长江路7号'}
dict1 = {'姓名':'张三','性别':'男','学历':'本科','生日':'1997-8-7',} dict1.update(学历='研究生') #参数是字典,没有返回值 dict2 = {'住址':'长江路7号'} # 定义一个字典 dict1.update(dict2) print(dict1) # {'姓名': '张三', '性别': '男', '学历': '研究生', '生日': '1997-8-7', '住址': '长江路7号'}
字典常用方法就讲到这里,学习了这么多,来做一个练习吧!
我为大家找了一个很好的例子,《用python实现词频统计》打开它练习一下吧。
如果对你有帮助,不要忘记点赞评论关注加收藏哦!