文章目录
数据类型是用来记录事物状态的,而事物的状态是不断变化的(如:一个人年龄的增长(操作int类型) ,单个人名的修改(操作str类型),学生列表中增加学生(操作list类型)等),这意味着我们在开发程序时需要频繁对数据进行操作,为了提升我们的开发效率, python针对这些常用的操作,为每一种数据类型内置了一系列方法
一、整数类型(int)详解
整数就是没有小数部分的数字,Python中的整数包括正整数、0 和负整数
有些强类型的编程语言会提供多种整数类型,每种类型的长度都不同,能容纳的整数的大小也不同,开发者要根据实际数字的大小选用不同的类型。例如C语言提供了 short、int、long、long long 四种类型的整数,它们的长度依次递增,初学者在选择整数类型时往往比较迷惑,有时候还会导致数值溢出。
而 Python 则不同,它的整数不分类型,或者说它只有一种类型的整数。Python 整数的取值范围是无限的,不管多大或者多小的数字,Python 都能轻松处理。Python 对整数的处理能力非常强大。不管对于多大或者多小的整数,Python 只用一种类型存储,就是 int
当所用数值超过计算机自身的计算能力时,Python 会自动转用高精度计算(大数计算)
1.1 整数的不同进制
在 Python 中,可以使用多种进制来表示整数:
1) 十进制形式
我们平时常见的整数就是十进制形式,它由 0~9 共十个数字排列组合而成。
注意,使用十进制形式的整数不能以 0 作为开头,除非这个数值本身就是 0。
2) 二进制形式
由 0 和 1 两个数字组成,书写时以0b
或0B
开头。例如,101 对应十进制数是 5。
3) 八进制形式
八进制整数由 0~7 共八个数字组成,以0o
或0O
开头。注意,第一个符号是数字 0,第二个符号是大写或小写的字母 O。
在 Python 2.x 中,八进制数字还可以直接以0
(数字零)开头。
4) 十六进制形式
由 0~9 十个数字以及 A~F(或 a~f)六个字母组成,书写时以0x
或0X
开头
#十六进制
hex1 = 0x45
hex2 = 0x4Af
print("hex1Value: ", hex1)
print("hex2Value: ", hex2)
#二进制
bin1 = 0b101
print('bin1Value: ', bin1)
bin2 = 0B110
print('bin2Value: ', bin2)
#八进制
oct1 = 0o26
print('oct1Value: ', oct1)
oct2 = 0O41
print('oct2Value: ', oct2)
# 运行结果:
hex1Value: 69
hex2Value: 1199
bin1Value: 5
bin2Value: 6
oct1Value: 22
oct2Value: 33
# 本例的输出结果都是十进制整数
# 进制转换
# 十进制转其他进制
bin(3) #二进制
# '0b11'
oct(9) #八进制
# '0o11'
hex(17) #十六进制
# '0x11'
# 其他进制转十进制
int('0b11',2)
# 3
int('0o11',8)
# 9
int('0x11',16)
# 17
1.2 数字分隔符
为了提高数字的的可读性,Python 3.x 允许使用下划线_
作为数字(包括整数和小数)的分隔符。通常每隔三个数字添加一个下划线,类似于英文数字中的逗号。下划线不会影响数字本身的值
distance = 384_000_000
print("地球和月球的距离:", distance)
1.3 相关方法
# 1、数据类型转换
# 1.1 int可以将由纯整数构成的字符串直接转换成整型,若包含其他任意非整数符号,则会报错
s = '123'
res = int(s)
print(res,type(res))
# (123, <class 'int'>)
print(int('12.3')) # 错误演示:字符串内包含了非整数符号.
#Traceback (most recent call last):
# File "<stdin>", line 1, in <module>
#ValueError: invalid literal for int() with base 10: '12.3'
# 1.2 进制转换
# 十进制转其他进制
print(bin(3))
#'0b11'
print(oct(9))
#'0o11'
print(hex(17))
# '0x11'
# 其他进制转十进制
print(int('0b11',2))
#3
print(int('0o11',8))
#9
print(int('0x11',16))
#17
# 1.3 float同样可以用来做数据类型的转换
s = '12.3'
res=float(s)
print(res,type(res))
#(12.3, <class 'float'>)
二、字符串类型(string)详解
若干个字符的集合就是一个字符串(String)。Python 中的字符串必须由双引号" "
或者单引号' '
包围,具体格式为:
"字符串内容"
'字符串内容'
字符串的内容可以包含字母、标点、特殊符号、中文、日文等全世界的所有文字
Python 字符串中的双引号和单引号没有任何区别。而有些编程语言的双引号字符串可以解析变量,单引号字符串一律原样输出,例如 PHP和JavaScript。
2.1 处理字符串中的引号的
当字符串内容中出现引号时,我们需要进行特殊处理,否则 Python 会解析出错
'I'm a great coder!'
由于上面字符串中包含了单引号,此时 Python 会将字符串中的单引号与第一个单引号配对,这样就会把'I'
当成字符串,而后面的m a great coder!'
就变成了多余的内容,从而导致语法错误。
对于这种情况,我们有两种处理方案:
1) 对引号进行转义
在引号前面添加反斜杠\
就可以对引号进行转义,让 Python 把它作为普通文本对待
str1 = 'I\'m a great coder!'
str2 = "引文双引号是\",中文双引号是“"
print(str1)
print(str2)
2) 使用不同的引号包围字符串
如果字符串内容中出现了单引号,那么我们可以使用双引号包围字符串,反之亦然
str1 = "I'm a great coder!" #使用双引号包围含有单引号的字符串
str2 = '引文双引号是",中文双引号是“' #使用单引号包围含有双引号的字符串
print(str1)
print(str2)
2.2字符串的换行
Python 不是格式自由的语言,它对程序的换行、缩进都有严格的语法要求。要想换行书写一个比较长的字符串,必须在行尾添加反斜杠\
s2 = 'It took me six months to write this Python tutorial. \
Please give me more support. \
I will keep it updated.'
num = 20 + 3 / 4 + \
2 * 3
print(num)
上面 s2 字符串的比较长,所以使用了转义字符\
对字符串内容进行了换行,这样就可以把一个长字符串写成多行。另外,Python 也支持表达式的换行
2.3 Python长字符串
使用三个单引号或者双引号可以对多行内容进行注释,这其实是 Python 长字符串的写法。所谓长字符串,就是可以直接换行(不用加反斜杠\
)书写的字符串
Python 长字符串由三个双引号"""
或者三个单引号'''
包围
"""长字符串内容"""
'''长字符串内容'''
在长字符串中放置单引号或者双引号不会导致解析错误
如果长字符串没有赋值给任何变量,那么这个长字符串就不会起到任何作用,和一段普通的文本无异,相当于被注释掉了。
注意,此时 Python 解释器并不会忽略长字符串,也会按照语法解析,只是长字符串起不到实际作用而已。
当程序中有大段文本内容需要定义成字符串时,优先推荐使用长字符串形式,因为这种形式非常强大,可以在字符串中放置任何内容,包括单引号和双引号
2.4 Python原始字符串
Python 字符串中的反斜杠\
有着特殊的作用,就是转义字符
转义字符有时候会带来一些麻烦,例如我要表示一个包含 Windows 路径D:\Program Files\Python 3.8\python.exe
这样的字符串,在 Python 程序中直接这样写肯定是不行的,不管是普通字符串还是长字符串。因为\
的特殊性,我们需要对字符串中的每个\
都进行转义,也就是写成D:\\Program Files\\Python 3.8\\python.exe
这种形式才行
这种写法需要特别谨慎,稍有疏忽就会出错。为了解决转义字符的问题,Python 支持原始字符串。在原始字符串中,\
不会被当作转义字符,所有的内容都保持“原汁原味”的样子
在普通字符串或者长字符串的开头加上r
前缀,就变成了原始字符串,具体格式为
str1 = r'原始字符串内容'
str2 = r"""原始字符串内容"""
Python 支持的转义字符
转义字符 | 说明 |
---|---|
\n | 换行符,将光标位置移到下一行开头 |
\r | 回车符,将光标位置移到本行开头 |
\t | 水平制表符,也即 Tab 键,一般相当于四个空格 |
\a | 蜂鸣器响铃。注意不是喇叭发声,现在的计算机很多都不带蜂鸣器了,所以响铃不一定有效 |
\b | 退格(Backspace),将光标位置移到前一列 |
\\ | 反斜线 |
\' | 单引号 |
\" | 双引号 |
\ | 在字符串行尾的续行符,即一行未完,转到下一行继续写 |
转义字符在书写形式上由多个字符组成,但 Python 将它们看作是一个整体,表示一个字符
2.5 Python序列详解
所谓序列,指的是一块可存放多个值的连续内存空间,这些值按一定顺序排列,可通过每个值所在位置的编号(称为索引)访问它们。
为了更形象的认识序列,可以将它看做是一家旅店,那么店中的每个房间就如同序列存储数据的一个个内存空间,每个房间所特有的房间号就相当于索引值。也就是说,通过房间号(索引)我们可以找到这家旅店(序列)中的每个房间(内存空间)。
在Python中,序列类型包括字符串、列表、元组、集合和字典,这些序列支持以下几种通用的操作,但比较特殊的是,集合和字典不支持索引、切片、相加和相乘操作。
字符串也是一种常见的序列,它也可以直接通过索引访问字符串内的字符
2.5.1 序列索引
序列中,每个元素都有属于自己的编号(索引)。从起始元素开始,索引值从 0 开始递增
除此之外,Python 还支持索引值是负数,此类索引是从右向左计数,换句话说,从最后一个元素开始计数,从索引值 -1 开始
注意,在使用负值作为列序中各元素的索引值时,是从 -1 开始,而不是从 0 开始
无论是采用正索引值,还是负索引值,都可以访问序列中的任何元素
2.5.2 序列切片
切片操作是访问序列中元素的另一种方法,它可以访问一定范围内的元素,通过切片操作,可以生成一个新的序列
序列实现切片操作的语法格式如下
sname[start : end : step]
其中,各个参数的含义分别是
- sname:表示序列的名称
- start:表示切片的开始索引位置(包括该位置),此参数也可以不指定,会默认为 0,也就是从序列的开头进行切片
- end:表示切片的结束索引位置(不包括该位置),如果不指定,则默认为序列的长度
- step:表示在切片过程中,隔几个存储位置(包含当前位置)取一次元素,也就是说,如果 step 的值大于 1,则在进行切片去序列元素时,会“跳跃式”的取元素。如果省略设置 step 的值,则最后一个冒号就可以省略
2.5.3 序列相加
Python 中,支持两种类型相同的序列使用“+”运算符做相加操作,它会将两个序列进行连接,但不会去除重复的元素
这里所说的“类型相同”,指的是“+”运算符的两侧序列要么都是列表类型,要么都是元组类型,要么都是字符串
print('我是'+'木易')
2.5.4 序列相乘
Python 中,使用数字 n 乘以一个序列会生成新的序列,其内容为原来序列被重复 n 次的结果
print('我是木易'*3)
比较特殊的是,列表类型在进行乘法运算时,还可以实现初始化指定长度列表的功能
list = ['1']*5
print(list)
# [1,1,1,1,1]
2.5.5 检查元素是否包含在序列中
Python 中,可以使用 in 关键字检查某元素是否为序列的成员,其语法格式为
value in sequence
其中,value 表示要检查的元素,sequence 表示指定的序列
和 in 关键字用法相同,但功能恰好相反的,还有 not in 关键字,它用来检查某个元素是否不包含在指定的序列中
str = '我是木易'
print('我' in str)
# True
print('我' not in str)
# False
2.5.6 和序列相关的内置函数
Python提供了几个内置函数,可用于实现与序列相关的一些常用操作
函数 | 功能 |
---|---|
len() | 计算序列的长度,即返回序列中包含多少个元素 |
max() | 找出序列中的最大元素。注意,对序列使用 sum() 函数时,做加和操作的必须都是数字,不能是字符或字符串,否则该函数将抛出异常,因为解释器无法判定是要做连接操作(+ 运算符可以连接两个序列),还是做加和操作 |
min() | 找出序列中的最小元素 |
list() | 将序列转换为列表 |
str() | 将序列转换为字符串 |
sum() | 计算元素和 |
sorted() | 对元素进行排序 |
reversed() | 反向序列中的元素 |
enumerate() | 将序列组合为一个索引序列,多用在 for 循环中 |
2.6 相关方法
2.6.1 优先掌握的操作
str1 = 'hello python!'
# 1.按索引取值(正向取,反向取):
# 1.1 正向取(从左往右)
print(str1[6])
#p
# 1.2 反向取(负号表示从右往左)
print(str1[-4])
#h
# 1.3 对于str来说,只能按照索引取值,不能改
str1[0]='H' # 报错TypeError
# 2.切片(顾头不顾尾,步长)
# 2.1 顾头不顾尾:取出索引为0到8的所有字符
print(str1[0:9])
#hello pyt
# 2.2 步长:0:9:2,第三个参数2代表步长,会从0开始,每次累加一个2即可,所以会取出索引0、2、4、6、8的字符
print(str1[0:9:2])
#hlopt
# 2.3 反向切片
print(str1[::-1]) # -1表示从右往左依次取值
#!nohtyp olleh
# 3.长度len
# 3.1 获取字符串的长度,即字符的个数,但凡存在于引号内的都算作字符)
print(len(str1)) # 空格也算字符
#13
# 4.成员运算 in 和 not in
# 4.1 int:判断hello 是否在 str1里面
print('hello' in str1)
#True
# 4.2 not in:判断tony 是否不在 str1里面
print('tony' not in str1)
#True
# 5.strip移除字符串首尾指定的字符(默认移除空格)
# 5.1 括号内不指定字符,默认移除首尾空白字符(空格、\n、\t)
str1 = ' life is short! '
print(str1.strip())
#life is short!
# 5.2 括号内指定字符,移除首尾指定的字符
str2 = '**tony**'
print(str2.strip('*'))
# tony
# 6.切分split
# 6.1 括号内不指定字符,默认以空格作为切分符号
str3='hello world'
print(str3.split())
#['hello', 'world']
# 6.2 括号内指定分隔字符,则按照括号内指定的字符切割字符串
str4 = '127.0.0.1'
print(str4.split('.'))
#['127', '0', '0', '1'] # 注意:split切割得到的结果是列表数据类型
# 7.循环
str5 = '今天你好吗?'
for line in str5: # 依次取出字符串中每一个字符
print(line)
2.6.2 需要掌握的操作
-
strip,lstrip,rstrip
str1 = '**tony***' print(str1.strip('*')) # 移除左右两边的指定字符 #'tony' print(str1.lstrip('*')) # 只移除左边的指定字符 #tony*** print(str1.rstrip('*')) # 只移除右边的指定字符 #**tony
-
lower(),upper()
str2 = 'My nAme is tonY!' print(str2.lower()) # 将英文字符串全部变小写 #my name is tony! print(str2.upper()) # 将英文字符串全部变大写 #MY NAME IS TONY!
-
startswith,endswith
str3 = 'tony jam'
# startswith()判断字符串是否以括号内指定的字符开头,结果为布尔值True或False
print(str3.startswith('t'))
# True
print(str3.startswith('j'))
# False
# endswith()判断字符串是否以括号内指定的字符结尾,结果为布尔值True或False
print(str3.endswith('jam'))
# True
print(str3.endswith('tony'))
# False
- 格式化输出之format
# format括号内在传参数时完全可以打乱顺序,但仍然能指名道姓地为指定的参数传值,name=‘tony’就是传给{name}
str4 = 'my name is {name}, my age is {age}!'.format(age=18,name='tony')
print(str4)
# 'my name is tony, my age is 18!'
str4 = 'my name is {name}{name}{name}, my age is {name}!'.format(name='tony', age=18)
print(str4)
# 'my name is tonytonytony, my age is tony!'
# 类似于%s的用法,传入的值会按照位置与{}一一对应
str4 = 'my name is {}, my age is {}!'.format('tony', 18)
print(str4)
# my name is tony, my age is 18!
# 把format传入的多个值当作一个列表,然后用{索引}取值
str4 = 'my name is {0}, my age is {1}!'.format('tony', 18)
print(str4)
# my name is tony, my age is 18!
str4 = 'my name is {1}, my age is {0}!'.format('tony', 18)
print(str4)
# my name is 18, my age is tony!
str4 = 'my name is {1}, my age is {1}!'.format('tony', 18)
print(str4)
# my name is 18, my age is 18!
- split,rsplit
# split会按照从左到右的顺序对字符串进行切分,可以指定切割次数
str5='C:/a/b/c/d.txt'
print(str5.split('/',1))
# ['C:', 'a/b/c/d.txt']
# rsplit刚好与split相反,从右往左切割,可以指定切割次数
str5='a|b|c'
print(str5.rsplit('|',1))
# ['a|b', 'c']
- join
# 从可迭代对象中取出多个字符串,然后按照指定的分隔符进行拼接,拼接的结果为字符串
print('%'.join('hello')) # 从字符串'hello'中取出多个字符串,然后按照%作为分隔符号进行拼接
#'h%e%l%l%o'
print('|'.join(['tony','18','read'])) # 从列表中取出多个字符串,然后按照*作为分隔符号进行拼接
# 'tony|18|read'
- replace
# 用新的字符替换字符串中旧的字符
str7 = 'my name is tony, my age is 18!' # 将tony的年龄由18岁改成73岁
str7 = str7.replace('18', '73') # 语法:replace('旧内容', '新内容')
print(str7)
# my name is tony, my age is 73!
# 可以指定修改的个数
str7 = 'my name is tony, my age is 18!'
str7 = str7.replace('my', 'MY',1) # 只把一个my改为MY
print(str7)
# 'MY name is tony, my age is 18!'
- isdigit
# 判断字符串是否是纯数字组成,返回结果为True或False
str8 = '5201314'
print(str8.isdigit())
# True
str8 = '123g123'
print(str8.isdigit())
# False
2.6.3 了解操作
# 1.find,rfind,index,rindex,count
# 1.1 find:从指定范围内查找子字符串的起始索引,找得到则返回数字1,找不到则返回-1
msg='tony say hello'
print(msg.find('o',1,3)) # 在索引为1和2(顾头不顾尾)的字符中查找字符o的索引
#1
# 1.2 index:同find,但在找不到时会报错
print(msg.index('e',2,4)) # 报错ValueError
# 1.3 rfind与rindex:略
# 1.4 count:统计字符串在大字符串中出现的次数
msg = "hello everyone"
print(msg.count('e')) # 统计字符串e出现的次数
# 4
print(msg.count('e',1,6)) # 字符串e在索引1~5范围内出现的次数
# 1
# 2.center,ljust,rjust,zfill
name='tony'
print(name.center(30,'-')) # 总宽度为30,字符串居中显示,不够用-填充
# -------------tony-------------
print(name.ljust(30,'*')) # 总宽度为30,字符串左对齐显示,不够用*填充
# tony**************************
print(name.rjust(30,'*')) # 总宽度为30,字符串右对齐显示,不够用*填充
# **************************tony
print(name.zfill(50)) # 总宽度为50,字符串右对齐显示,不够用0填充
# 0000000000000000000000000000000000000000000000tony
# 3.expandtabs
name = 'tony\thello' # \t表示制表符(tab键)
print(name)
# tony hello
print(name.expandtabs(1)) # 修改\t制表符代表的空格数
# tony hello
# 4.captalize,swapcase,title
# 4.1 captalize:首字母大写
message = 'hello everyone nice to meet you!'
print(message.capitalize())
# Hello everyone nice to meet you!
# 4.2 swapcase:大小写翻转
message1 = 'Hi girl, I want make friends with you!'
print(message1.swapcase())
# hI GIRL, i WANT MAKE FRIENDS WITH YOU!
#4.3 title:每个单词的首字母大写
msg = 'dear my friend i miss you very much'
print(msg.title())
# Dear My Friend I Miss You Very Much
# 5.is数字系列
#在python3中
num1 = b'4' #bytes
num2 = u'4' #unicode,python3中无需加u就是unicode
num3 = '四' #中文数字
num4 = 'Ⅳ' #罗马数字
#isdigt:bytes,unicode
print(num1.isdigit())
# True
print(num2.isdigit())
# True
print(num3.isdigit())
# False
print(num4.isdigit())
# False
#isdecimal:uncicode(bytes类型无isdecimal方法)
print(num2.isdecimal())
# True
print(num3.isdecimal())
# False
print(num4.isdecimal())
# False
#isnumberic:unicode,中文数字,罗马数字(bytes类型无isnumberic方法)
print(num2.isnumeric())
# True
print(num3.isnumeric())
# True
print(num4.isnumeric())
# True
# 三者不能判断浮点数
num5 = '4.3'
print(num5.isdigit())
# False
print(num5.isdecimal())
# False
print(num5.isnumeric())
# False
'''
总结:
最常用的是isdigit,可以判断bytes和unicode类型,这也是最常见的数字应用场景
如果要判断中文数字或罗马数字,则需要用到isnumeric。
'''
# 6.is其他
name = 'tony123'
print(name.isalnum()) #字符串中既可以包含数字也可以包含字母
# True
print(name.isalpha()) #字符串中只包含字母
# False
print(name.isidentifier())
# True
print(name.islower()) # 字符串是否是纯小写
# True
print(name.isupper()) # 字符串是否是纯大写
# False
print(name.isspace()) # 字符串是否全是空格
# False
print(name.istitle()) # 字符串中的单词首字母是否都是大写
# False
三、列表(List)详解
在实际开发中,经常需要将一组(不只一个)数据存储起来,以便后边的代码使用。C语言,C++, JAVA, PHP等编程语言中是数组(Array),它可以把多个数据挨个存储到一起,通过数组下标可以访问数组中的每个元素。
Python中没有数组,但是加入了更加强大的列表list
从形式上看,列表会将所有元素都放在一对中括号[ ]
里面,相邻元素之间用逗号,
分隔
[element1, element2, element3, ..., elementn]
格式中,element1 ~ elementn 表示列表中的元素,个数没有限制,只要是 Python 支持的数据类型就可以
从内容上看,列表可以存储整数、小数、字符串、列表、元组等任何类型的数据,并且同一个列表中元素的类型也可以不同
注意,在使用列表时,虽然可以将不同类型的数据放入到同一个列表中,但通常情况下不这么做,同一列表中只放入同一类型的数据,这样可以提高程序的可读性
3.1 创建列表
在 Python 中,创建列表的方法可分为两种
1) 使用 [ ] 直接创建列表
使用[ ]
创建列表后,一般使用=
将它赋值给某个变量
listname = [element1 , element2 , element3 , ... , elementn]
其中,listname 表示变量名,element1 ~ elementn 表示列表元素
使用此方式创建列表时,列表中元素可以有多个,也可以一个都没有,创建空列表
2) 使用 list() 函数创建列表
除了使用[ ]
创建列表外,Python 还提供了一个内置的函数 list(),使用它可以将其它数据类型转换为列表类型
#将字符串转换成列表
list1 = list("hello")
print(list1)
#将元组转换成列表
tuple1 = ('Python', 'Java', 'C++', 'JavaScript')
list2 = list(tuple1)
print(list2)
#将字典转换成列表
dict1 = {'a':100, 'b':42, 'c':9}
list3 = list(dict1)
print(list3)
#将区间转换成列表
range1 = range(1, 6)
list4 = list(range1)
print(list4)
#创建空列表
print(list())
3.2 访问列表元素
列表是 Python 序列的一种,我们可以使用索引(Index)访问列表中的某个元素(得到的是一个元素的值),也可以使用切片访问列表中的一组元素(得到的是一个新的子列表)
使用索引访问列表元素的格式
listname[i]
其中,listname 表示列表名字,i 表示索引值。列表的索引可以是正数,也可以是负数
使用切片访问列表元素的格式为
listname[start : end : step]
其中,listname 表示列表名字,start 表示起始索引,end 表示结束索引,step 表示步长
3.3 删除列表
对于已经创建的列表,如果不再使用,可以使用del
关键字将其删除
实际开发中并不经常使用 del 来删除列表,因为 Python 自带的垃圾回收机制会自动销毁无用的列表,即使开发者不手动删除,Python 也会自动将其回收
del 关键字的语法格式为
del listname
其中,listname 表示要删除列表的名称
3.4 相关方法
3.4.1 优先掌握的操作
# 1.按索引存取值(正向存取+反向存取):即可存也可以取
# 1.1 正向取(从左往右)
my_friends=['tony','jason','tom',4,5]
print(my_friends[0])
# tony
# 1.2 反向取(负号表示从右往左)
print(my_friends[-1])
# 5
# 1.3 对于list来说,既可以按照索引取值,又可以按照索引修改指定位置的值,但如果索引不存在则报错
my_friends = ['tony','jack','jason',4,5]
my_friends[1] = 'martthow'
print(my_friends)
# ['tony', 'martthow', 'jason', 4, 5]
# 2.切片(顾头不顾尾,步长)
# 2.1 顾头不顾尾:取出索引为0到3的元素
print(my_friends[0:4])
# ['tony', 'jason', 'tom', 4]
# 2.2 步长:0:4:2,第三个参数2代表步长,会从0开始,每次累加一个2即可,所以会取出索引0、2的元素
print(my_friends[0:4:2])
# ['tony', 'tom']
# 3.长度
print(len(my_friends))
# 5
# 4.成员运算in和not in
print('tony' in my_friends)
# True
print('xxx' not in my_friends)
# True
# 5.添加
# 5.1 append()列表尾部追加元素
l1 = ['a','b','c']
l1.append('d')
print(l1)
# ['a', 'b', 'c', 'd']
# 5.2 extend()一次性在列表尾部添加多个元素
l1.extend(['a','b','c'])
print(l1)
# ['a', 'b', 'c', 'd', 'a', 'b', 'c']
# 5.3 insert()在指定位置插入元素
l1.insert(0,"first") # 0表示按索引位置插值
print(l1)
# ['first', 'a', 'b', 'c', 'alisa', 'a', 'b', 'c']
# 6.删除
# 6.1 del
l = [11,22,33,44]
del l[2] # 删除索引为2的元素
print(l)
# [11,22,44]
# 6.2 pop()默认删除列表最后一个元素,并将删除的值返回,括号内可以通过加索引值来指定删除元素
l = [11,22,33,22,44]
res=l.pop()
print(res)
# 44
res=l.pop(1)
print(res)
# 22
# 6.3 remove()括号内指名道姓表示要删除哪个元素,没有返回值
l = [11,22,33,22,44]
res=l.remove(22) # 从左往右查找第一个括号内需要删除的元素
print(res)
# None
# 7.reverse()颠倒列表内元素顺序
l = [11,22,33,44]
l.reverse()
print(l)
# [44,33,22,11]
# 8.sort()给列表内所有元素排序
# 8.1 排序时列表元素之间必须是相同数据类型,不可混搭,否则报错
l = [11,22,3,42,7,55]
l.sort()
print(l)
#[3, 7, 11, 22, 42, 55] # 默认从小到大排序
l = [11,22,3,42,7,55]
l.sort(reverse=True) # reverse用来指定是否跌倒排序,默认为False
print(l)
# [55, 42, 22, 11, 7, 3]
# 8.2 了解知识:
# 我们常用的数字类型直接比较大小,但其实,字符串、列表等都可以比较大小,原理相同:都是依次比较对应位置的元素的大小,如果分出大小,则无需比较下一个元素,比如
l1=[1,2,3]
l2=[2,]
print(l2 > l1)
# True
# 字符之间的大小取决于它们在ASCII表中的先后顺序,越往后越大
s1='abc'
s2='az'
print(s2 > s1) # s1与s2的第一个字符没有分出胜负,但第二个字符'z'>'b',所以s2>s1成立
# True
# 所以我们也可以对下面这个列表排序
l = ['A','z','adjk','hello','hea']
l.sort()
print(l)
# ['A', 'adjk', 'hea', 'hello','z']
# 9.循环
# 循环遍历my_friends列表里面的值
for line in my_friends:
print(line)
3.4.2 了解操作
l=[1,2,3,4,5,6]
print(l[0:3:1])
# [1, 2, 3] # 正向步长
print(l[2::-1])
# [3, 2, 1] # 反向步长
# 通过索引取值实现列表翻转
print(l[::-1])
# [6, 5, 4, 3, 2, 1]
四、 元祖(tuple)详解
元组(tuple)是 Python中另一个重要的序列结构,和列表类似,元组也是由一系列按特定顺序排序的元素组成
元组和列表(list)的不同之处在于:
- 列表的元素是可以更改的,包括修改元素值,删除和插入元素,所以列表是可变序列
- 而元组一旦被创建,它的元素就不可更改了,所以元组是不可变序列
元组也可以看做是不可变的列表,通常情况下,元组用于保存无需修改的内容
从形式上看,元组的所有元素都放在一对小括号( )
中,相邻元素之间用逗号,
分隔
(element1, element2, ... , elementn)
其中 element1~elementn 表示元组中的各个元素,个数没有限制,只要是 Python 支持的数据类型就可以
从存储内容上看,元组可以存储整数、实数、字符串、列表、元组等任何类型的数据,并且在同一个元组中,元素的类型可以不同
4.1 创建元祖
Python 提供了两种创建元组的方法
1) 使用 ( ) 直接创建
通过( )
创建元组后,一般使用=
将它赋值给某个变量
tuplename = (element1, element2, ..., elementn)
其中,tuplename 表示变量名,element1 ~ elementn 表示元组的元素
在 Python 中,元组通常都是使用一对小括号将所有元素包围起来的,但小括号不是必须的,只要将各元素用逗号隔开,Python 就会将其视为元组
当创建的元组中只有一个字符串类型的元素时,该元素后面必须要加一个逗号
,
,否则 Python 解释器会将它视为字符串
2) 使用tuple()函数创建元组
除了使用( )
创建元组外,Python 还提供了一个内置的函数 tuple(),用来将其它数据类型转换为元组类型
tuple(data)
其中,data 表示可以转化为元组的数据,包括字符串、元组、range 对象等
#将字符串转换成元组
tup1 = tuple("hello")
print(tup1)
#将列表转换成元组
list1 = ['Python', 'Java', 'C++', 'JavaScript']
tup2 = tuple(list1)
print(tup2)
#将字典转换成元组
dict1 = {'a':100, 'b':42, 'c':9}
tup3 = tuple(dict1)
print(tup3)
#将区间转换成元组
range1 = range(1, 6)
tup4 = tuple(range1)
print(tup4)
#创建空元组
print(tuple())
4.2 访问元祖元素
和列表一样,我们可以使用索引(Index)访问元组中的某个元素(得到的是一个元素的值),也可以使用切片访问元组中的一组元素(得到的是一个新的子元组)
使用索引访问元组元素的格式为
tuplename[i]
其中,tuplename 表示元组名字,i 表示索引值。元组的索引可以是正数,也可以是负数
使用切片访问元组元素的格式
tuplename[start : end : step]
其中,start 表示起始索引,end 表示结束索引,step 表示步长
4.3 修改元祖
元组是不可变序列,元组中的元素不能被修改,所以我们只能创建一个新的元组去替代旧的元组
可以通过连接多个元组(使用+
可以拼接元组)的方式向元组中添加新元素
tup1 = (100, 0.5, -36, 73)
tup2 = ( -54.6, 99)
print(tup1+tup2)
print(tup1)
print(tup2)
使用+
拼接元组以后,tup1 和 tup2 的内容没法发生改变,这说明生成的是一个新的元组
4.4 删除元祖
当创建的元组不再使用时,可以通过 del 关键字将其删除
Python 自带垃圾回收功能,会自动销毁不用的元组,所以一般不需要通过 del 来手动删除
4.5 元组和列表的区别
元组和列表同属序列类型,且都可以按照特定顺序存放一组数据,数据类型不受限制,只要是 Python 支持的数据类型就可以。那么,元组和列表有哪些区别呢?
元组和列表最大的区别就是,列表中的元素可以进行任意修改,就好比是用铅笔在纸上写的字,写错了还可以擦除重写;而元组中的元素无法修改,除非将元组整体替换掉,就好比是用圆珠笔写的字,写了就擦不掉了,除非换一张纸
可以理解为,tuple 元组是一个只读版本的 list 列表
元组的性能速度要优于列表
listdemo = []
print(listdemo.__sizeof__())
# 40
tupleDemo = ()
print(tupleDemo.__sizeof__())
# 24
对于列表和元组来说,虽然它们都是空的,但元组却比列表少占用 16 个字节
由于列表是动态的,它需要存储指针来指向对应的元素(占用 8 个字节)。另外,由于列表中元素可变,所以需要额外存储已经分配的长度大小(占用 8 个字节)。但是对于元组,情况就不同了,元组长度大小固定,且存储元素不可变,所以存储空间也是固定的
通过对比列表和元组存储方式的差异,我们可以引申出这样的结论,即元组要比列表更加轻量级,所以从总体上来说,元组的性能速度要优于列表
总的来说,元组确实没有列表那么多功能,但是元组依旧是很重要的序列类型之一,元组的不可替代性体现在以下这些场景中:
- 元组作为很多内置函数和序列类型方法的返回值存在,也就是说,在使用某些函数或者方法时,它的返回值会元组类型,因此你必须对元组进行处理
- 元组比列表的访问和处理速度更快,因此,当需要对指定元素进行访问,且不涉及修改元素的操作时,建议使用元组
- 元组可以在映射(和集合的成员)中当做“键”使用,而列表不行
4.6 相关方法
tuple1 = (1, 'hhaha', 15000.00, 11, 22, 33)
# 1、按索引取值(正向取+反向取):只能取,不能改否则报错!
print(tuple1[0])
# 1
print(tuple1[-2])
# 22
tuple1[0] = 'hehe' # 报错:TypeError:
# 2、切片(顾头不顾尾,步长)
print(tuple1[0:6:2])
# (1, 15000.0, 22)
# 3、长度
print(len(tuple1))
# 6
# 4、成员运算 in 和 not in
print('hhaha' in tuple1 )
#True
print('hhaha' not in tuple1 )
#False
# 5、循环
for line in tuple1:
print(line)
五、字典类型(Dict)详解
字典(dict)是一种无序的、可变的序列,它的元素以“键值对(key-value)”的形式存储。相对地,列表(list)和元组(tuple)都是有序的序列,它们的元素在底层是挨着存放的
字典类型是 Python 中唯一的映射类型。“映射”是数学中的术语,简单理解,它指的是元素之间相互对应的关系,即通过一个元素,可以唯一找到另一个元素
字典中,习惯将各元素对应的索引称为键(key),各个键对应的元素称为值(value),键及其关联的值称为“键值对”
字典类型很像学生时代常用的新华字典。我们知道,通过新华字典中的音节表,可以快速找到想要查找的汉字。其中,字典里的音节表就相当于字典类型中的键,而键对应的汉字则相当于值
总的来说,字典类型所具有的主要特征如表所示
主要特征 | 解释 |
---|---|
通过键而不是通过索引来读取元素 | 字典类型有时也称为关联数组或者散列表(hash)。它是通过键将一系列的值联系起来的,这样就可以通过键从字典中获取指定项,但不能通过索引来获取 |
字典是任意数据类型的无序集合 | 和列表、元组不同,通常会将索引值 0 对应的元素称为第一个元素,而字典中的元素是无序的 |
字典是可变的,并且可以任意嵌套 | 字典可以在原处增长或者缩短(无需生成一个副本),并且它支持任意深度的嵌套,即字典存储的值也可以是列表或其它的字典 |
字典中的键必须唯一 | 字典中,不支持同一个键出现多次,否则只会保留最后一个键值对 |
字典中的键必须不可变 | 字典中每个键值对的键是不可变的,只能使用数字、字符串或者元组,不能使用列表 |
5.1 创建字典
1) 使用 { } 创建字典
由于字典中每个元素都包含两部分,分别是键(key)和值(value),因此在创建字典时,键和值之间使用冒号:
分隔,相邻元素之间使用逗号,
分隔,所有元素放在大括号{ }
中
使用{ }
创建字典的语法格式
dictname = {'key':'value1', 'key2':'value2', ..., 'keyn':valuen}
其中 dictname 表示字典变量名,keyn : valuen 表示各个元素的键值对。需要注意的是,同一字典中的各个键必须唯一,不能重复
#使用字符串作为key
scores = {'数学': 95, '英语': 92, '语文': 84}
print(scores)
#使用元组和数字作为key
dict1 = {(20, 30): 'great', 30: [1,2,3]}
print(dict1)
#创建空元组
dict2 = {}
print(dict2)
可以看到,字典的键可以是整数、字符串或者元组,只要符合唯一和不可变的特性就行;字典的值可以是 Python 支持的任意数据类型
2) 通过 fromkeys() 方法创建字典
Python 中,还可以使用 dict 字典类型提供的 fromkeys() 方法创建带有默认值的字典
dictname = dict.fromkeys(list,value=None)
其中,list 参数表示字典中所有键的列表(list);value 参数表示默认值,如果不写,则为空值 None
knowledge = ['语文', '数学', '英语']
scores = dict.fromkeys(knowledge, 60)
print(scores)
knowledge 列表中的元素全部作为了 scores 字典的键,而各个键对应的值都是 60。这种创建方式通常用于初始化字典,设置 value 的默认值
3) 通过 dict() 映射函数创建字典
通过 dict() 函数创建字典的写法有多种,罗列出了常用的几种方式,它们创建的都是同一个字典 a
a = dict(str1=value1, str2=value2, str3=value3)
# str 表示字符串类型的键,value 表示键对应的值。使用此方式创建字典时,字符串不能带引号
#方式1
demo = [('two',2), ('one',1), ('three',3)]
#方式2
demo = [['two',2], ['one',1], ['three',3]]
#方式3
demo = (('two',2), ('one',1), ('three',3))
#方式4
demo = (['two',2], ['one',1], ['three',3])
a = dict(demo)
# 向 dict() 函数传入列表或元组,而它们中的元素又各自是包含 2 个元素的列表或元组,其中第一个元素作为键,第二个元素作为值。
keys = ['one', 'two', 'three'] #还可以是字符串或元组
values = [1, 2, 3] #还可以是字符串或元组
a = dict( zip(keys, values) )
# 通过应用 dict() 函数和 zip() 函数,可将前两个列表转换为对应的字典
注意,无论采用以上哪种方式创建字典,字典中各元素的键都只能是字符串、元组或数字,不能是列表。列表是可变的,不能作为键
如果不为 dict() 函数传入任何参数,则代表创建一个空的字典
5.2 访问字典
列表和元组是通过下标来访问元素的,而字典不同,它通过键来访问对应的值。因为字典中的元素是无序的,每个元素的位置都不固定,所以字典也不能像列表和元组那样,采用切片的方式一次性访问多个元素
Python 访问字典元素的具体格式
dictname[key]
其中,dictname 表示字典变量的名字,key 表示键名。注意,键必须是存在的,否则会抛出异常
除了上面这种方式外,Python 更推荐使用 dict 类型提供的 get() 方法来获取指定键对应的值。当指定的键不存在时,get() 方法不会抛出异常
dictname.get(key[,default])
其中,dictname 表示字典变量的名字;key 表示指定的键;default 用于指定要查询的键不存在时,此方法返回的默认值,如果不手动指定,会返回 None。当键不存在时,get() 返回空值 None,如果想明确地提示用户该键不存在,那么可以手动设置 get() 的第二个参数
5.3 删除字典
和删除列表、元组一样,手动删除字典也可以使用 del 关键字
Python 自带垃圾回收功能,会自动销毁不用的字典,所以一般不需要通过 del 来手动删除
5.4 相关方法
5.4.1 优先掌握的操作
# 1、按key存取值:可存可取
# 1.1 取
dic = {
'name': 'xxx',
'age': 18,
'hobbies': ['play game', 'basketball']
}
print(dic['name'])
# 'xxx'
print(dic['hobbies'][1])
# 'basketball'
# 1.2 对于赋值操作,如果key原先不存在于字典,则会新增key:value
dic['gender'] = 'male'
print(dic)
# {'name': 'tony', 'age': 18, 'hobbies': ['play game', 'basketball'],'gender':'male'}
# 1.3 对于赋值操作,如果key原先存在于字典,则会修改对应value的值
dic['name'] = 'tony'
print(dic)
# {'name': 'tony', 'age': 18, 'hobbies': ['play game', 'basketball']}
# 2、长度len
print(len(dic))
# 3
# 3、成员运算in和not in
print('name' in dic) # 判断某个值是否是字典的key
# True
# 4、删除
dic.pop('name') # 通过指定字典的key来删除字典的键值对
print(dic)
# {'age': 18, 'hobbies': ['play game', 'basketball']}
# 5、键keys(),值values(),键值对items()
dic = {'age': 18, 'hobbies': ['play game', 'basketball'], 'name': 'xxx'}
# 获取字典所有的key
print(dic.keys())
# dict_keys(['name', 'age', 'hobbies'])
# 获取字典所有的value
print(dic.values())
# dict_values(['xxx', 18, ['play game', 'basketball']])
# 获取字典所有的键值对
print(dic.items())
# dict_items([('name', 'xxx'), ('age', 18), ('hobbies', ['play game', 'basketball'])])
# 6、循环
# 6.1 默认遍历的是字典的key
for key in dic:
print(key)
# 6.2 只遍历key
for key in dic.keys():
print(key)
# 6.3 只遍历value
for key in dic.values():
print(key)
# 6.4 遍历key与value
for key in dic.items():
print(key)
5.4.2 需要掌握的操作
-
get()
dic= {'k1':'jason','k2':'Tony','k3':'JY'} print(dic.get('k1')) # 'jason' # key存在,则获取key对应的value值 res=dic.get('xxx') # key不存在,不会报错而是默认返回None print(res) # None res=dic.get('xxx',666) # key不存在时,可以设置默认返回的值 print(res) # 666 # ps:字典取值建议使用get方法
-
pop()
dic= {'k1':'jason','k2':'Tony','k3':'JY'} v = dic.pop('k2') # 删除指定的key对应的键值对,并返回值 print(dic) # {'k1': 'jason', 'kk2': 'JY'} print(v) # 'Tony'
-
popitem()
dic= {'k1':'jason','k2':'Tony','k3':'JY'} item = dic.popitem() # 随机删除一组键值对,并将删除的键值放到元组内返回 print(dic) # {'k3': 'JY', 'k2': 'Tony'} print(item) # ('k1', 'jason')
-
update()
# 用新字典更新旧字典,有则修改,无则添加 dic= {'k1':'jason','k2':'Tony','k3':'JY'} dic.update({'k1':'JN','k4':'xxx'}) print(dic) # {'k1': 'JN', 'k3': 'JY', 'k2': 'Tony', 'k4': 'xxx'}
-
fromkeys()
dic = dict.fromkeys(['k1','k2','k3'],[]) print(dic) # {'k1': [], 'k2': [], 'k3': []}
-
setdefault()
# key不存在则新增键值对,并将新增的value返回 dic={'k1':111,'k2':222} res=dic.setdefault('k3',333) print(res) # 333 print(dic) # 字典中新增了键值对 # {'k1': 111, 'k3': 333, 'k2': 222} # key存在则不做任何修改,并返回已存在key对应的value值 dic={'k1':111,'k2':222} res=dic.setdefault('k1',666) print(res) # 111 print(dic) # 字典不变 # {'k1': 111, 'k2': 222}
六、集合类型(Set)详解
Python中的集合,和数学中的集合概念一样,用来保存不重复的元素,即集合中的元素都是唯一的,互不相同。集合主要用于:去重、关系运算
从形式上看,和字典类似,Python 集合会将所有元素放在一对大括号 {} 中,相邻元素之间用“,”分隔
{element1,element2,...,elementn}
其中,elementn 表示集合中的元素,个数没有限制
从内容上看,同一集合中,只能存储不可变的数据类型,包括整形、浮点型、字符串、元组,无法存储列表、字典、集合这些可变的数据类型,否则 Python 解释器会抛出 TypeError 错误
并且需要注意的是,数据必须保证是唯一的,因为集合对于每种数据元素,只会保留一份
由于 Python 中的 set 集合是无序的,所以每次输出时元素的排序顺序可能都不相同
定义:在{}内用逗号分隔开多个元素,集合具备以下三个特点:
- 每个元素必须是不可变类型
- 集合内没有重复的元素
- 集合内元素无序
6.1 创建set集合
Python 提供了 2 种创建 set 集合的方法,分别是使用 {} 创建和使用 set() 函数将列表、元组等类型数据转换为集合
1) 使用 {} 创建
在 Python 中,创建 set 集合可以像列表、元素和字典一样,直接将集合赋值给变量,从而实现创建集合的目的
setname = {element1,element2,...,elementn}
其中,setname 表示集合的名称,起名时既要符合 Python 命名规范,也要避免与 Python 内置函数重名
2) set()函数创建集合
set() 函数为 Python 的内置函数,其功能是将字符串、列表、元组、range 对象等可迭代对象转换成集合
setname = set(iteration)
其中,iteration 就表示字符串、列表、元组、range 对象等数据
6.2 访问set集合元素
由于集合中的元素是无序的,因此无法向列表那样使用下标访问元素。Python 中,访问集合元素最常用的方法是使用循环结构,将集合中的数据逐一读取出来
a = {1,'c',1,(1,2,3),'c'}
for ele in a:
print(ele,end=' ')
6.3 删除set集合
和其他序列类型一样,手动删除集合类型,也可以使用 del() 语句
6.4 相关方法
6.4.1 关系运算
我们定义两个集合friends与friends2来分别存放两个人的好友名字,然后以这两个集合为例讲解集合的关系运算
friends1 = {"zero","kevin","jason","egon"} # 用户1的好友们
friends2 = {"Jy","ricky","jason","egon"} # 用户2的好友们
两个集合的关系
# 1.合集/并集(|):求两个用户所有的好友(重复好友只留一个)
print(friends1 | friends2)
# {'kevin', 'ricky', 'zero', 'jason', 'Jy', 'egon'}
# 2.交集(&):求两个用户的共同好友
print(friends1 & friends2)
# {'jason', 'egon'}
# 3.差集(-):
print(friends1 - friends2) # 求用户1独有的好友
# {'kevin', 'zero'}
print(friends2 - friends1) # 求用户2独有的好友
# {'ricky', 'Jy'}
# 4.对称差集(^) # 求两个用户独有的好友们(即去掉共有的好友)
print(friends1 ^ friends2)
# {'kevin', 'zero', 'ricky', 'Jy'}
# 5.值是否相等(==)
print(friends1 == friends2)
# False
# 6.父集:一个集合是否包含另外一个集合
# 6.1 包含则返回True
print({1,2,3} > {1,2})
# True
print({1,2,3} >= {1,2})
# True
# 6.2 不存在包含关系,则返回False
print({1,2,3} > {1,3,4,5})
# False
print({1,2,3} >= {1,3,4,5})
# False
# 7.子集
print({1,2} < {1,2,3})
# True
print({1,2} <= {1,2,3})
# True
6.4.2 去重
集合去重复有局限性
- 只能针对不可变类型
- 集合本身是无序的,去重之后无法保留原来的顺序
l=['a','b',1,'a','a']
s=set(l)
print(s) # 将列表转成了集合
# {'b', 'a', 1}
l_new=list(s) # 再将集合转回列表
print(l_new)
# ['b', 'a', 1] # 去除了重复,但是打乱了顺序
# 针对不可变类型,并且保证顺序则需要我们自己写代码实现,例如
l=[
{'name':'lili','age':18,'sex':'male'},
{'name':'jack','age':73,'sex':'male'},
{'name':'tom','age':20,'sex':'female'},
{'name':'lili','age':18,'sex':'male'},
{'name':'lili','age':18,'sex':'male'},
]
new_l=[]
for dic in l:
if dic not in new_l:
new_l.append(dic)
print(new_l)
# 结果:既去除了重复,又保证了顺序,而且是针对不可变类型的去重
# [
# {'age': 18, 'sex': 'male', 'name': 'lili'},
# {'age': 73, 'sex': 'male', 'name': 'jack'},
# {'age': 20, 'sex': 'female', 'name': 'tom'}
# ]
6.4.3 其他操作
# 1.长度
s={'a','b','c'}
print(len(s))
# 3
# 2.成员运算
print('c' in s)
# True
# 3.循环
for item in s:
print(item)
七、可变类型与不可变类型
可变数据类型:值发生改变时,内存地址不变,即id不变,证明在改变原值[列表,字典,集合]
不可变类型:值发生改变时,内存地址也发生改变,即id也变,证明是没有在改变原值,是产生了新的值[数字,字符串,元祖]