Python基本数据类型的常用操作和内置方法
参考声明:本文参考了菜鸟教程、Python官方文档及部分百度搜索结果显示的网络资源等内容,结合个人经验进行了整理
在1.1中已经对个数据类型进行了简单说明和区分,其中也包含了可变与不可变类型的分类,此处就不再涉及。
仅分别从各个数据类型入手,总结其各自的常用操作及内置方法。
1.字符串类型(不可变类型):
1.1.字符串定义:
Python中关于字符串变量的定义一般有三种(单引号和双引号可以嵌套,但必须前后对应):
str1 = '单引号!'
str2 = "双引号!"
str3 = """
多行用三引号
三个单引号
或三个双引号
均可!
"""
print(str1, str2, str3) ==>
单引号! 双引号!
多行用三引号
三个单引号
或三个双引号
均可!
1.2.字符串索引(取出来的都是一个新的字符串对象):
str1, str2 = 'string1'
print(str1[3]) # i ==> 像列表一样,可以通过下标索引取出指定位置上的单个字符
print(str1[0:5:2]) # srn ==> 像列表一样,可以通过下标索引切片取出指定位置上的某几个字符得到新的字符串(可以设置步长)
1.3.字符串拼接(得到的也是新的字符串对象):
str1, str2 = 'string1', 'string2'
print(str1, str2, 123) # string1 string2 123 ==> 1.在print语句中使用','分隔多个数据对象,输出会默认用空格分隔
print(str1 + str2) # string1string2 ==> 2.直接使用'+',表示将后一个字符串直接连接到前一个字符串末尾,没有分隔
print(str1 * 2) # string1string1 ==> 3.对某个字符串使用乘法,表示将被乘字符串重复拼接N次
1.4.使用转义字符:
1.4.1在字符串中,有时会需要转义字符来达到我们的目的,举几个常见的转义字符:
1.'\n' ==> 表示换行;
2.'\r' ==> 回车;
3.'\b' ==> 退格(Backspace);
4.\' ==> 单引号
5.\" ==> 双引号;
6.'\\' ==> 反斜杠符号;
7.'\v' ==> 纵向制表符; 8.'\t' ==> 横向制表符
1.4.2.再举两个应用的例子:
1.换行符:
str1, str2 = 'string1', 'string2'
print(str1+'\n'+str2) ==> 运行会发现,不同于前面的单纯拼接,在str1打印之后,str2是换行之后才打印
2.反斜杠(常见于文件路径):
str1 = 'E:\Python\pythonProject\图灵Python\核心编程第八期\课程笔记'
str2 = 'E:\\Python\\pythonProject\\图灵Python\\核心编程第八期\\课程笔记'
print(str2) ==> 转义输出:E:\Python\pythonProject\图灵Python\核心编程第八期\课程笔记
print(str1 == str2) ==> 判定结果为True
1.4.3.有时候,字符串中出现了转义字符,但是我们并不想让他转义,在Python中可以使用r'string\n123',表示这是一个源字符串
这样里面的\n就会被当做普通字符输出:
str1 = 'E:\Python\pythonProject\图灵Python\核心编程第八期\课程笔记'
str2 = r'E:\\Python\\pythonProject\\图灵Python\\核心编程第八期\\课程笔记' # 使用了r包裹字符串
print(str2) ==> 原样输出:E:\\Python\\pythonProject\\图灵Python\\核心编程第八期\\课程笔记
print(str1 == str2) ==> 判定结果为False
1.4.字符串格式化:
1.4.1.使用格式化符号%:
这里和C语言中的格式化输出基本一致,也像C语言一样有很多占位符,就不一一列举了。只举一个简单例子:
str1, int1 = 'string1', 123
print('hello: %s---%d!!!' % (str1, int1)) # hello: string1---123!!!
1.4.2.Python2.6以后可以使用str.format()方法,统一用{}占位,还可以根据索引指定位置:
print('hello: {}---{}!!!'.format(str1, int1)) # hello: string1---123!!!
print('hello: {1}---{0}!!!'.format(str1, int1)) # hello: 123---string1!!! ==> 根据索引指定位置
1.4.3.Python3.6以后还可以使用 f"hello: {str1}---{int1}!!!"格式化字符串,更快、更易读、更简明且不易出错:
print(f'hello: {str1}---{int1}!!!') # hello: string1---123!!!
1.5. 字符串运算符:
1.+ ==> 字符串连接
2.* ==> 重复输出字符串
3.[] ==> 通过索引获取字符串中字符
4.[起始:结束:步长] ==>截取字符串中的一部分
5.in ==> 成员运算符, 如果字符串中包含给定的字符返回 True
6.not in ==> 成员运算符, 如果字符串中不包含给定的字符返回 True
7.r/R ==> 源字符串,不进行特殊字符输出或转义,其他与普通字符串一致。
8.% ==> 格式字符串
1.6.字符串常用操作和内置方法:
这里介绍字符串常用的操作或方法,包含大多数方法(使用频率仅代表个人日常习惯):
1.len(str): 常用,获取对象的长度,对象包含字符串、列表、字典等
2.del str: 常用,删除对象,是与赋值key=value相对应的,赋值会创建一个对象,而del则是销毁这个对象,因此不仅包含字符串。
3.max(str)和min(str):偶尔,返回对象中最大和最小元素,对字符串使用时返回字符串str 中最大/小的字母。
4.str.encode(encoding='UTF-8', errors='strict') 字符串编码
str.decode(encoding='UTF-8', errors='strict') 字符串解码:
以encoding指定的编码格式解码/解码 字符串str,如果出错默认报一个ValueError的异常,除非errors指定的是'ignore'或者'replace'
5.str.format():格式化字符串。看个人习惯,本人用f-string格式化多一点
6.str.split(str1, num):一个特别常用的方法,可以将给定字符串中包含的str1作为分隔符,得到切分后的列表
str ==> 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
num ==> 分割次数。默认为 -1, 即分隔所有。
与之相对的有rsplit:从后向前进行分割
例如:print('abcabcabc'.split('b')) # ['a', 'ca', 'ca', 'c']
应当注意,作为分隔符的字符串不会出现在结果中(单纯起到分隔的依据),另外如果分隔符出现在字符串首/尾,结果列表的
首尾会多一个空串
7.str.lstrip()、str.rstrip()、str.strip() ==> 偶尔需要,修剪操作:去掉字符串 左/右/两侧 的空格或指定字符。
8.str.replace(old, new, max) ==> 比较常用,字符串替换,将str中的old替换为new,max可以指定替换次数,默认为所有
例如:print('abcabcabc'.replace('b', '+')) # a+ca+ca+c
9.str.join(seq):比较常用,将seq序列中的元素以指定的字符连接生成一个新的字符串。
例如:print('+'.join(['1', '23', 'abc'])) # 1+23+abc
10.str.count(sub, start, end): 偶尔,统计str里sub出现的次数。可指定字符串搜索的开始与结束位置(左闭右开)。
11.str.startswith(substr, beg, end)和str.endswith(suffix, start, end):
有时会用,判断字符串是否以substr 结尾/开头,是则返回 True,否则返回 False。
12.str.ljust(width, fillchar)、str.center(width, fillchar)、str.rjust(width, fillchar):
较少用,返回一个指定的宽度width的居 左/中/右 的字符串,width小于字符串宽度直接返回字符串,否则用fillchar填充。
13.str.zfill(width):偶尔需要,返回指定长度的字符串,不够长度则左边补0,否则返回原字符串。相当于rjust(width, '0')
例如:print('123'.zfill(5)) # 00123 ==> rjust(5, '0')
print('123'.rjust(5, '0') == '123'.zfill(5)) # True
14.str.find(str1, start, end)和str.index(str, start, end):偶尔需要
1.都是: 检测str中是否包含str1 ,指定范围内如果包含str1,返回的是str1第一次出现的索引值。
2.区别: 如果不包含,那么 str.find()会返回-1,str.index()会直接报错
str.rfind(str, beg, end)和str.rindex(str, beg, end):
与上面两种相反,返回的是最后一次出现的索引值。区别也一致
15.str.capitalize()、str.upper()、str.lower()、str.swapcase()、str.title() 格式化系列: 较少用
str.capitalize() ==> 将字符串的第一个字母变成大写,其他字母变小写。
str.upper() ==> 将字符串中的小写字母转为大写字母。
str.lower() ==> 转换字符串中所有大写字符为小写。
str.swapcase() ==> 对字符串的大小写字母进行转换,小写变大写,大写变小写。
str.title() ==> 返回"标题化"的字符串,所有单词的首个字母转化为大写,其余字母均为小写。
16.str.isalnum()、str.isalpha()、str.isdigit()、str.isnumeric()、str.islower()、str.isspace()、
str.istitle()、str.isupper() is检测系列:偶尔用
str.isalnum() ==> 检测字符串是否由字母和数字组成。
str.isalpha() ==> 检测字符串是否只由字母或文字组成。
str.isdigit() ==> 检测字符串是否只由数字组成。
str.isnumeric() ==> 检测字符串是否只由数字组成。
str.islower() ==> 检测字符串是否由小写字母组成。
str.isspace() ==> 检测字符串是否只由空白字符组成。
str.istitle() ==> 检测字符串中所有的单词拼写首字母是否为大写,且其他字母为小写。
str.isupper() ==> 检测字符串中所有的字母是否都为大写。
2.数字类型(将整数、浮点数等统称为数字进行解释):
与字符串一样,数字类型是不可变的,这就意味着如果改变Number数据类型的值,将重新分配内存空间。
因此,可以使用del语句人为删除一些Number对象引用。
关于数字的一些操作,结合数学知识可以更好地理解。
2.1.几种数值类型:
Python 支持四种不同的数值类型:
整型(int):通常被称为是整型或整数,是正或负整数,不带小数点。
长整型(long integers):无限大小的整数,整数最后是一个大写或小写的L(Python3移除)。
浮点型(floating point real values):浮点型由整数部分与小数部分组成,浮点型也可以使用科学计数法表示(2.5e2 = 2.5 x 102 = 250)
复数(complex numbers):复数由实数部分和虚数部分构成,可以用a + bj,或者complex(a,b)表示, 复数的实部a和虚部b都是浮点型。
注意:在Python3里,只有一种整数类型int,表示为整型,没有python2中的长整型Long。
2.2.基本运算与赋值:
2.2.1.数字赋值语句:
1.'=' ==> 普通赋值 a = b ==> 等价形式
2.'+=' ==> 加法赋值 a += b ==> a = a+b
3.'-=' ==> 减法赋值 a -= b ==> a = a-b
4.'*=' ==> 乘法赋值 a *= b ==> a = a*b
5.'/=' ==> 除法赋值 a /= b ==> a = a/b
6.'//=' ==> 整除赋值 a //= b ==> a = a//b
7.'%=' ==> 取余赋值 a %= b ==> a = a%b
8.'**=' ==> 乘方赋值 a **= b ==> a = a**b
2.2.2.基本运算:
基本的四则运算应该都知道,也包括2.2.1中几种赋值语句的等价形式。
这里提一个比较好用的方法是eval(str):用来计算在字符串中的有效Python表达式,并返回一个对象:
例如:print(eval('3*5')) # 15
对于数字当然可以直接计算,但是字符串形式的表达式串可以用这个方法来直接计算,这个方法也仅限于有效表达式字符串,本人曾在
简易计算器中偷懒,使用了这个方法直接计算表达式的结果^_^.
另外,一些基本类型是可以转换的,比如整数字符串可以转换为整数、数字(不限于整数)也可以转换为字符串形式:
str(11) ==> '11'; int('123') ==> 123
2.2.3.数学常量:
一些数学字符不好表示,所以Python内置了数学常量,例如:
pi 数学常量 pi(圆周率,一般以π来表示)
e 数学常量 e,e即自然常数(自然常数)。
2.2.4.数学运算库:
一些数学运算使用基本的运算不好实现,因此Python内置了数学方法模块math 模块和cmath 模块,
Python 中数学运算常用的函数基本都在 math 模块、cmath 模块中。
Python math 模块提供了许多对浮点数的数学运算函数。
Python cmath 模块包含了一些用于复数运算的函数。
cmath 模块的函数跟 math 模块函数基本一致,区别是 cmath 模块运算的是复数,math 模块运算的是数学运算。
数学中常见的像abs(计算绝对值)、pow(计算次方)、round(四舍五入)、log(对数运算)、三角函数等均有包含。
详细的不做介绍,可以直接查阅官方文档,如何使用需要根据自己的编程经历慢慢积累。
Python3 math函数库官方文档:https://docs.python.org/3/library/math.html
3.布尔类型(表示真或假,一般以True和False为代表)
关于Python中布尔值的几点说明:
1.所有的数据类型都自带布尔值,可以在判断条件中当做真或假来用
2.None,0,空(空字符串,空列表,空字典,)三种情况下布尔值为False,
3.其余均可看做True
4.列表
4.1.列表的简单介绍
不同于字符串、数字和布尔类型,列表不仅是Python的一种数据类型,它也是Python中极为常见的数据结构之一,根据本人习惯,用
到列表和字典(与json相互转换很方便)较多,而元组相对较少,而且因为列表和字典都是属于可变类型,个人感觉用来存储数据非常
灵活。
Python中的列表形式类似于C语言的数组,当然Java也有列表。由于Python中变量的定义很简单,我们可以这样定义一个列表:
list1 = [] # 空列表 也可以使用list(seq)将可迭代序列转换为列表,seq为空时得到空列表
list2 = [1, 2, 3] # 纯数字列表
print(type(list1)) # <class 'list'> ==> 列表类型
值得一提的是,由于Python中对于数据类型的限制比较弱(个人认为有利有弊吧),同一列表中可以存多种不同类型的数据对象,而并没
有特定的限制数字列表只能存数字,字符串列表只能存字符串等,如果灵活利用这点有些时候是很方便的。示例如下:
list3 = [123, 'abc', {'name': 'ZhangSan'}, [1, 2, 3], ('a', 'b')] # 存放不同类型的列表
4.2.列表元素的访问:
4.2.1.单个元素:
像C语言的数组、Java的列表一样,直接通过下标索引访问,例如:
list1 = [1, 2, 3, 4, 5]
print(list1[0]) # 下标从0开始
print(list1[2]) # 下标2 ==> 对应第2+1=3个元素
按照索引的方向,有正向索引和负向索引,
(1)正向即从左向右,下标为:0, 1, 2, 3..., end
(2)负向即从右向左,下标为:-1, -2, -3..., 0
也就是说同一元素可通过两种下标都能访问到:
print(list1[len(list1) - 1] is list1[-1]) # True ==> 正向最后一个元素和逆向第一个元素是同一个元素。
4.2.2.列表切片:
就是根据范围和步长取出一批元素组成新的列表,直接看例子:
print(list1[0:5:2]) # [1, 3, 5] ==> list[start:end:step] 需要注意索引范围[start,end)是前闭后开的
如果不指定start默认为0,不指定end默认为列表长度+1(范围前闭右开,不填默认遍历包含到最后一个元素),不指定step默认为1
print(list1[0:len(list1) + 1:1] == list1[::]) # True ==> 包含的元素相同,但实际为两个列表对象
4.3.列表基本运算:
print(len(list1)) # 4 ==> 列表长度
print(list1 + list2) # [1, 2, 3, 4, 4, 5, 6, 7] ==> 列表相加,列表的元素是可以重复的
print(list1 * 2) # [1, 2, 3, 4, 1, 2, 3, 4] ==> 相当于list1+list1(可以对比str*int理解)
print([item for item in list1[0:3]]) # [1, 2, 3] ==> 列表生成式:将满足条件的item组成新的列表
print(2 in list1, 2 not in list2) # True True ==> in:判断元素是否在可迭代对象内(不限于列表);not in:与in相反
4.4.列表常用函数和内置方法:
4.4.1.列表常用函数:
1.cmp(obj1, obj2) ==> 比较两个对象(不限于列表)
需要注意:python3移除了cmp()函数,又提供了六个丰富的比较运算符(包含在operator中):
import operator #需要导入运算符模块
operator.gt(1,2) #greater than(大于)
operator.ge(1,2) #greater and equal(大于等于)
operator.eq(1,2) #equal(等于)
operator.le(1,2) #less and equal(小于等于)
operator.lt(1,2) #less than(小于)
operator中还包含了很多其他的方法,都是常见的运算操作。
2.len(list) ==> 列表长度,前面提过,len是一个比较通用的求可迭代对象长度的方法
3.max(list) ==> 返回列表元素最大值元素
4.min(list) ==> 返回列表元素最小值元素
5.list(seq) ==> 将可迭代(重点)序列转换为列表
例如list('123') ==> ['1', '2', '3'], 但是list(123)就不被允许
又如list((1,2,3)) ==> [1, 2, 3] # 元组转换为列表
4.4.2.列表内置方法:
1.list.append(obj) ==> 在列表末尾添加新的对象
2.list.count(obj) ==> 统计某个元素在列表中出现的次数
3.list.extend(seq) ==> 在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表)
4.list.index(obj) ==> 从列表中找出某个值第一个匹配项的索引位置
5.list.insert(index, obj) ==> 将对象插入到列表指定位置index
6.list.pop([index=-1]) ==> 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值
7.list.remove(obj) ==> 移除列表中某个值的第一个匹配项(如果需要销毁元素对象,建议del list[index])
8.list.reverse() ==> 反转列表中元素:[1, 2, 3]->[3, 2, 1],注意该方法没有返回值,是在原列表基础修改:
print(list1.reverse()) # None
print(list1) # [4, 3, 2, 1]
9.list.sort( key=None, reverse=False) ==> 对原列表进行排序(同reverse,修改了原列表)
10.list.clear() ==> 清空列表
11.list.copy() ==> 复制列表(深拷贝,复制到一个新的对象):
print(id(list1.copy())) # 1462738501696
print(id(list1)) # 1463048071680
Python如果使用赋值语句,其实是一种浅拷贝(只是建立了一个联系,两个变量指向的是同一个内存地址,踩过坑hh):
list2 = list1
print(id(list1)) # 3213046504000
print(id(list2)) # 3213046504000
b = a = 1 # 注意其他语言可能不支持连等操作
print(a is b) # True ==> a,b指向同一个对象
5.元组
5.1.元组的简单介绍
5.1.1.定义一个新元组:
tuple_ = () # 可以使用()定义一个空元组,也可以使用tuple(seq)将可迭代序列转换为元组,seq为空时得到空元组
print(type(tuple_)) # <class 'tuple'>
tuple_ = 1, 2, 3 # 实测Python3用一个变量名接收一个序列作为元组可以不用带括号 ==> 等价tuple_ = (1, 2, 3)
print(tuple_) # (1, 2, 3)
5.1.2.元组的索引:
元组的索引与列表一样,有两种方向的索引。这里引用菜鸟教程的一张图来说明:
原文链接:https://www.runoob.com/python3/python3-tuple.html
5.1.3.元组是不可变类型:
元组是属于不可变类型,因此一经创建不支持修改(添加新元素,删除某个元素,修改某个元素值)操作,所以只支持访问操作及其他
不改变其值的操作,并且也没有内置的append和remove操作。例如以下操作是非法的:
tuple_ = ('a', 'b', 'c', 1, 2, 3)
tuple_[2] = 'd' # 修改异常:TypeError: 'tuple' object does not support item assignment
del tuple_[2] # 删除异常:TypeError: 'tuple' object doesn't support item deletion
del tuple_ # 只能删除整个元组对象
5.2.元组元素的访问与列表基本一致,此处不再做详细说明:
tuple_ = ('a', 'b', 'c', 1, 2, 3)
print(tuple_[2]) # c ==> 访问下标为2的元素(第三个元素)
print(tuple_[::2]) # ('a', 'c', 2) ==> 以步长为2对元组所有元素进行切片(会生成新的元组对象)
5.3.元组的基本运算:
元组的基本运算和前面列表支持的基本运算一致(组合和重复会生成新对象):
tuple1 = ('a', 'b', 'c', 1)
tuple2 = (1, 2, 3)
print(len(tuple1)) # 4 ==> 元组长度
print(tuple1 + tuple2) # ('a', 'b', 'c', 1, 1, 2, 3) ==> 元组相加,元组的元素也是可以重复的
print(tuple1 * 2) # ('a', 'b', 'c', 1, 'a', 'b', 'c', 1) ==> 相当于list1+list2(可以对比str*number理解)
print([item for item in tuple2[0:3]]) # [1, 2, 3] ==> 元组也支持迭代操作(可迭代序列)
print(2 in tuple1, 2 not in tuple2) # False False ==> in:判断元素是否在可迭代对象内;not in:与in相反
5.4.元组常用函数和内置方法
由于元组的不可变,其没有列表那些内置方法,只有index()和count()。这也是我用元组少的原因之一吧,不过我认为每种数据类型
和数据结构的存在都有其独特性和合理性,只是适用的场景不同,所以这与我们日常的编程领域和习惯偏好也有关系。
常用函数也是那几种通用方法:len(tuple)/max(tuple)/min(tuple)/tuple(seq):将可迭代序列转换为元组
6.集合
6.1.集合的简单介绍
集合的概念可以联系数学中的集合理解,集合具有确定性、互异性(不存在重复元素)、无序性(不能通过下标索引)。
1.定义一个空集合应使用set()而不是{}:
set1 = {}
print(type(set1)) # <class 'dict'> ==> 因为字典和集合分界符相同,所以需要注意:{}默认为空字典
set1 = set()
print(type(set1)) # <class 'set'> ==> 创建空集合必须用set()
2.有初始序列的集合定义:
set1 = {'a', 'b', 'c', 1, 2, 3}
print(type(set1)) # <class 'set'> ==> 直接用{value1,value2...}
set1 = set('abc123')
print(type(set1)) # <class 'set'> ==> set()可以将可迭代序列转换为集合
6.2.关于集合特性的说明
1.由于集合具有互异性,因此常用于列表去重,即list(set(listobj)):
list1 = ['a', 'b', 'c', 1, 2, 3, 1, 2, 3]
print(list(set(list1))) # [1, 2, 3, 'b', 'a', 'c'] ==> 得到去重的列表
但是需要注意:由于集合的无序性,列表的索引顺序会发生改变,所以要根据实际需求决定是否用这种方式去重。
2.由于集合的无序性,因此无法直接通过索引访问集合元素,但是可以将其转换为列表后进行访问:
set1 = {'a', 'b', 'c', 1, 2, 3}
print(list(set1)) # [1, 2, 3, 'a', 'b', 'c'] ==> 集合转换为列表进行一些集合没有的操作
print(len(set1)) # 6 ==> 虽然不能直接访问集合的元素,但是通用方法len仍可以获取集合的元素个数
由于Python对于数据类型定义的约束较弱,所以在很多实际应用中,应当根据需求,灵活进行不同数据类型和结构的转换,
以达到我们的目标为原则。
3.集合的确定性,从数学定义来说就是一个元素相对于一个集合是确定的(只有属于和不属于两种情况):
set1 = {'a', 'b', 'c', 1, 2, 3}
if 'a' in set1: # 虽不能直接访问集合元素,但能判断元素是否属于集合
print('A')
6.3.集合的运算操作:
集合之间可以进行一些运算操作(注意集合没有+操作):
set1 = {'a', 'b', 'c', 1, 2, 3}
set2 = {'1', '2', '3', 1, 2, 3}
# 1.与运算,相当于求交集,两者共有的部分
print(set1 & set2) # {1, 2, 3}
# 2.或运算,相当于求并集,两者的元素共同构成更大的集合
print(set1 | set2) # {1, 2, 3, '3', 'a', '1', '2', 'c', 'b'}
# 3.减运算,相当于求差集:set1有而set2没有的,被减集合中除去两者重复的元素
print(set1 - set2) # {'b', 'a', 'c'}
# 4.异或运算,求两个集合不同的部分
print(set1 ^ set2) # {'3', 'a', '1', '2', 'c', 'b'}
# 5.像列表一样,集合也可以使用生成式
print({item for item in [1, 2, 3]}) # {1, 2, 3}
通常可以利用集合的以上运算及特性,来弥补列表部分操作上的不足,需要灵活运用!
6.4.集合的内置方法
1.add():新增元素,作用相当于列表中的append()方法
2.clear():清空集合元素
3.copy():像列表的复制一样,集合也支持拷贝方法
4.difference():返回多个集合的差集,集合求差集的内置方法。会生成新的集合
5.difference_update():移除集合中的元素,该元素在指定的集合也存在。无返回值,也是求差集,但是是在原集合上做修改。
set1 = {'a', 'b', 'c', 1, 2, 3}
set2 = {'1', '2', '3', 1, 2, 3}
set1.difference_update(set2)
print(set1) # {'b', 'c', 'a'} ==> 将结果保存到原集合,即求差并更新的含义
6.discard():删除集合中指定的元素
7.remove():移除指定元素
关于6和7的区别:
remove(...):
Remove an element from a set; it must be a member.If the element is not a member, raise a KeyError.
即 从集合中移除一个元素;它必须是成员。如果元素不是成员,则引发 KeyError。
discard(...):
Remove an element from a set if it is a member.If the element is not a member, do nothing.
即 如果它是成员,则从集合中删除一个元素。如果元素不是成员,则什么也不做。
简单来说就是当元素不存在时,remove会引发异常,但discard不会。
8.intersection():返回集合的交集
9.intersection_update():返回集合的交集并更新。与8的区别就像4和5的区别
10.isdisjoint():判断两个集合是否包含相同的元素,如果没有返回 True,否则返回 False。
11.issubset():判断指定集合是否为该方法参数集合的子集。
12.issuperset():判断该方法的参数集合是否为指定集合的子集。11和12是一组互逆的方法
13.pop():随机移除元素,类似于列表的pop方法
14.symmetric_difference():返回两个集合中不重复的元素集合。
15.symmetric_difference_update():移除当前集合中在另外一个指定集合相同的元素,并将另外一个指定集合中不同的元素插入到当前集合中。相对于14的更新方法
16.union():返回两个集合的并集
17.update():给集合添加元素,更新集合
7.字典
7.1.字典的简单介绍
字典的概念可以联系我们日常中的字典,汉语字典、英语字典、词典等进行理解。但是更为特殊一些,字典由键和值构成,
且键的内容不能重复,但是不同的键可以对应同一个值(通俗的可以联系字典的多音字)。
字典的键必须不可变,所以可以用数字,字符串或元组充当,而用列表就不能作为建,但是字典的值可以是任何类型的对象。
字典和集合一样使用{}包裹,但是每一个元素都是由键值对的形式出现,并且字典还可以像列表一样嵌套(集合不能嵌套集合和字典)
字典的定义:
dict1 = {} # 1.创建空字典,也可以使用dict()创建空字典
print(type(dict1)) # <class 'dict'> ==> {}默认为空字典,需要与集合区分
dict1 = {'a': 1, 'b': [1, 2, 3], 'user': {'name': 'ZhangSan', 'age': 20}} # 定义一个字典,可以嵌套不同的数据类型
print(dict1) # {'a': 1, 'b': [1, 2, 3], 'user': {'name': 'ZhangSan', 'age': 20}} ==> 字典的元素以键值对形式出现
7.2.字典内容的访问:
字典的访问也是一种索引访问,只不过列表用的是下标索引,字典用的是键作为索引:
dict1 = {'a': 1, 'b': [1, 2, 3], 'user': {'name': 'ZhangSan', 'age': 20}} # 定义一个字典
print(dict1['user']['name']) # ZhangSan ==> 字典可以通过键嵌套访问元素的内容
7.3.字典的内置方法和附加说明:
1.dict.clear():清空字典元素
2.dict.copy():字典也有复制方法
3.dict.fromkeys(seq):创建一个新字典,以序列seq中元素做字典的键,val为字典所有键对应的初始值:
print(dict.fromkeys([1, 2, 3])) # {1: None, 2: None, 3: None} ==> 以给定序列的元素为键,初值为None生成字典
4.dict.get(key, default=None):返回指定键的值,如果键不在字典中返回 default 设置的默认值
对于很多情况,我们可能不知道字典中是否存在某个键值对,建议使用get访问字典元素内容,否则直接用键进行索引当键不存在时会异常。
5.key in dict:如果键在字典dict里返回true,否则返回false
直接对dict使用in操作,默认判断的对象是字典的键
6.dict.items():以列表返回一个视图对象,列表的元素是(key,value)形式的二元组
本人非常常用,可用于以键值对形式遍历字典,相较于通过单变量遍历可以更为直接的获取当前遍历的键和值内容:
dict1 = {'a': 1, 'b': [1, 2, 3], 'user': {'name': 'ZhangSan', 'age': 20}} # 定义一个字典
for key in dict1: # 1.通过键遍历字典
print(f'{key}: {dict1[key]}') # 再根据键取出对应的值
# 2.通过键值对直接遍历字典 [('a', 1), ('b', [1, 2, 3]), ('user', {'name': 'ZhangSan', 'age': 20})]
print([(key, value) for key, value in dict1.items()])
7.dict.keys():返回一个视图对象,列表的元素为字典的键
8.dict.setdefault(key, default=None):和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
9.dict.update(dict2):把字典dict2的键/值对更新到dict里(相当于字典合并)
10.dict.values():返回一个视图对象,列表的元素为字典的值,对比6,7进行理解
11.pop(key[,default]):删除字典 key(键)所对应的值,同时返回被删除的值。
12.popitem():返回并删除字典中的最后一对键和值。对比11理解
个人的一点补充:
由于Python关于数据类型的定义和变量的赋值机制,暂且不考虑其弊端。Python的这个特点避免了在变量赋值时的很多麻烦。
1.在实际应用时,一定要灵活,特别是字典、集合、列表这几种特殊结构,以达到目标为原则。
例如列表去重在没有特殊要求时可以考虑转换为集合,字典遍历也可以考虑用items转换为二元组列表进行等;
2.一定要充分贯彻对象的概念,对于很多问题的解决很有帮助。
3.Python中这几种特殊数据结构的嵌套(字典、列表、元组等),可以自由发挥,定制成我们需要的数据结构,例如:
博客项目中将文章作为一个对象,文章与标签之间是多对多关联的关系,文章的作者是外键(关联用户表);
那么,如果将文章对象放在一个字典或列表内,那么文章对象(具有很多属性)用字典就很方便,文章的作者又是一个用户对象的字典
文章的标签有多个,因此标签的实际值应当以列表展示出来。
多种结构相互嵌套,共同构成文章这个对象。
4.关于字典,个人比较偏爱,因为日常编码中字典用的很多,而且在爬虫、web项目中字典是和json可以很方便相互转换的数据类型。
又由于字典结构的特殊性(以键值对形式排列),用途也很广泛,举几个个人经历过的例子:
1.用同一个接口对同一个对象进行类似的多种操作(action),例如对评论(comment)可以进行的操作有增加(add)。删除(delete)、
修改(modify)等,可以对这几种同为对评论的操作封装在一个接口,通过额外的action参数进行区分,而在后端处理时先用一个
评论操作分发器,字典就是一个很好的可以作为分发器的结构,而且相对于列表用下标索引,字典不用考虑数据项的先后顺序,因为
键是唯一的。那么分发器可以是如下形式:
comment_action = {
'add':comment_add, # 添加操作
'delete':comment_delete, # 删除操作
'modify':comment_modify, # 修改操作
... # 可扩展:由于不用考虑顺序问题,字典也具有很好的可扩展性。
}
然后需要根据action的标识去调用对应的操作:
comment_action[action]() # 带上括号表示方法的调用:取出对应的方法名,然后跟上()进行方法的调用
2.又如一个简单的单机游戏,可以分为菜单(选择开始游戏,游戏前阶段)、开始游戏后进入游戏中阶段、死亡或退出后需要有一个短暂的
转场处理(游戏后阶段),然后又回到菜单界面,如此循环就是一般的游戏流程。那么将这几个阶段进行封装,通过实例化对象来创建
对应阶段的游戏界面,进行一些绘制及其他处理操作。最后在游戏启动类(主程序),定义一个游戏阶段字典,防止对应的游戏阶段对象,
那么第一次启动时查字典先调用menu对应的值,加上()表示类的实例化,在每一个阶段内设置一个阶段结束的标志,再设置一个next属性
专门存放与当前阶段直接关联的下一阶段的键,达到死亡或计时等特定条件修改结束标志,通过更新方法检测这个标志判断当前阶段是否
结束,如果结束则根据next属性查字典,取出对应的下一阶段的类名,加上()进行类的实例化,从而进入下一阶段,完成游戏阶段的切换,
如此循环,一个游戏阶段的切换流程就实现了。
当然,每种结构都有其独特性和特殊操作,适用于不同的场景,因此除了要灵活切换,还应注意合理的选取合适的数据类型来进行编码,唯一原则
仍然是以完成我们的需求目标为最终目的。
这个部分内容较多,加上最近也在期末考试,断断续续抽空在整理,很多细节都查阅了资料,90%以上内容都是纯手打,整理这个系列笔记的目的
一是从头复习一下基础,二是查漏补缺,三是进行经验的积累,因为很多例子虽然简单,但都是临时编写,如果发现问题就需要进行思考,总结,
积累经验,随着后期的深入可能例子的难度会不断增加。希望我能一直坚持下去hh!!!