07 Python数据类型详解

文章目录


数据类型是用来记录事物状态的,而事物的状态是不断变化的(如:一个人年龄的增长(操作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 两个数字组成,书写时以0b0B开头。例如,101 对应十进制数是 5。

3) 八进制形式

八进制整数由 0~7 共八个数字组成,以0o0O开头。注意,第一个符号是数字 0,第二个符号是大写或小写的字母 O。

在 Python 2.x 中,八进制数字还可以直接以0(数字零)开头。

4) 十六进制形式

由 0~9 十个数字以及 A~F(或 a~f)六个字母组成,书写时以0x0X开头

#十六进制
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 需要掌握的操作

  1. strip,lstrip,rstrip

    str1 = '**tony***'
    
    print(str1.strip('*'))  # 移除左右两边的指定字符
    #'tony'
    print(str1.lstrip('*'))  # 只移除左边的指定字符
    #tony***
    print(str1.rstrip('*'))  # 只移除右边的指定字符
    #**tony
    
  2. lower(),upper()

    str2 = 'My nAme is tonY!'
    
    print(str2.lower())  # 将英文字符串全部变小写
    #my name is tony!
    print(str2.upper())  # 将英文字符串全部变大写
    #MY NAME IS TONY!
    
  3. 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
  1. 格式化输出之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!
  1. 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']
  1. join
# 从可迭代对象中取出多个字符串,然后按照指定的分隔符进行拼接,拼接的结果为字符串
print('%'.join('hello')) # 从字符串'hello'中取出多个字符串,然后按照%作为分隔符号进行拼接
#'h%e%l%l%o'
print('|'.join(['tony','18','read'])) # 从列表中取出多个字符串,然后按照*作为分隔符号进行拼接
# 'tony|18|read'
  1. 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!'
  1. 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 个字节)。但是对于元组,情况就不同了,元组长度大小固定,且存储元素不可变,所以存储空间也是固定的

通过对比列表和元组存储方式的差异,我们可以引申出这样的结论,即元组要比列表更加轻量级,所以从总体上来说,元组的性能速度要优于列表

总的来说,元组确实没有列表那么多功能,但是元组依旧是很重要的序列类型之一,元组的不可替代性体现在以下这些场景中:

  1. 元组作为很多内置函数和序列类型方法的返回值存在,也就是说,在使用某些函数或者方法时,它的返回值会元组类型,因此你必须对元组进行处理
  2. 元组比列表的访问和处理速度更快,因此,当需要对指定元素进行访问,且不涉及修改元素的操作时,建议使用元组
  3. 元组可以在映射(和集合的成员)中当做“键”使用,而列表不行

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 需要掌握的操作

  1. 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方法
    
  2. pop()

    dic= {'k1':'jason','k2':'Tony','k3':'JY'}
    v = dic.pop('k2')  # 删除指定的key对应的键值对,并返回值
    print(dic)
    # {'k1': 'jason', 'kk2': 'JY'}
    print(v)
    # 'Tony'
    
  3. popitem()

    dic= {'k1':'jason','k2':'Tony','k3':'JY'}
    item = dic.popitem()  # 随机删除一组键值对,并将删除的键值放到元组内返回
    print(dic)
    # {'k3': 'JY', 'k2': 'Tony'}
    print(item)
    # ('k1', 'jason')
    
  4. update()

    # 用新字典更新旧字典,有则修改,无则添加
    dic= {'k1':'jason','k2':'Tony','k3':'JY'}
    dic.update({'k1':'JN','k4':'xxx'})
    print(dic)
    # {'k1': 'JN', 'k3': 'JY', 'k2': 'Tony', 'k4': 'xxx'}
    
  5. fromkeys()

    dic = dict.fromkeys(['k1','k2','k3'],[])
    print(dic)
    # {'k1': [], 'k2': [], 'k3': []}
    
  6. 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 集合是无序的,所以每次输出时元素的排序顺序可能都不相同

定义:在{}内用逗号分隔开多个元素,集合具备以下三个特点:

  1. 每个元素必须是不可变类型
  2. 集合内没有重复的元素
  3. 集合内元素无序

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 去重

集合去重复有局限性

  1. 只能针对不可变类型
  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也变,证明是没有在改变原值,是产生了新的值[数字,字符串,元祖]

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值