第三章 数据类型
3.1整型(int)
3.1.1整型的长度
py2中有:int / long
py3中有:int (int / long) float
3.1.2整除
py2(需要多加一行的代码才能输出不整除的结果) py3正常
3.1.3强制转换int( )
1.将只含十进制的数字的字符串转换成整型,详细错误可见见第十三章(1)
2.将布尔值强制转换成整型,True转换成1,False转换成0
- 需要确定浮点数的小数位数用round函数
3.2布尔类型(bool)
用于表示真假,只有True和False
False(其他语言可能是小写), 特殊情况为整型的0和其他数据类型为空的时候
True
强制转换
bool(整数) bool(0) ---> False
bool(字符串) bool("") ---> False
bool(列表) bool([]) ---> False
bool(元组) bool(()) ---> False
dict(字典) bool() ---> False
set(集合) bool(set()) ---> False
v1=bool([]) v2=bool(()) print(v1,v2) #False False v3=() print(type(v3)) #<class 'tuple'> V4=(1) print(type(v4)) #<class 'int'> v5=(1,) print(type(v5)) #<class 'tuple'>
3.3字符串(str)
字符串是我们写代码中最常用的,python内存中的字符串时按照unicode编码存储,对于字符串来说是不可变的。
3.3.1字符串独有的功能
独有的功能 upper/lower/replace/join/encode/strip/split/startswith/endswith/isdecimal/format
转化大小写 upper() lower()
替换 replace()
#打野,大爷,大野,大爷, 打野, 大爷 message=input("请输入:") data=message.replace("大爷","**",2) #仅替换两次 print(data)
去除空格 "你所需要的字符串"等 strip/rstrip/lstrip()
#去除右边/左边/左边和右边 的空格+ + +"你所需要去除的字符串" new_name=" -->jjj<---- " print(new_name+"----") new_name1=new_name.lstrip() print(new_name1+"----") new_name2=new_name1.rstrip() print(new_name2+"-----") new_name3=new_name.strip() print(new_name3+"-----")
判断字符串是否可以转化为int型,返回布尔类型,可转化为int型返回True,用于判断十进制数推荐用isdecimal()
#num="1" #num="二" num="②" #这种字符不能转换成十进制数 v1=num.isdigit() #"1"-->True "二"-->False "②"-->True v2=num.isdecimal() #"1"-->True "二"-->False "②"-->False v3=num.isnumeric() #"1"-->True "二"-->True "②"-->True
划分 split / rsplit() / splitlines()根据换行分割
#message.split(',')/rsplit(',') 根据逗号来切割 message="小黑今天去吃了两碗面,结果没钱买单,被人打了一顿" result=message.split(',',1) #表示对第一个出现的中文逗号进行切分 result2=message.rsplit(',',1) #表示从右边开始对message切分 print(result) #输出为列表 print(result2)
partition() 找到第一个划分位置,将字符串划分成三份
v="aaaaabccccc" v1=v.partition("b") print(v1) #('aaaaa',"b","ccccc") #与split()不同的 是划分的份数永远是三个,而且中间是划分的依据
判断前几个字符是不是按照要求的 startswith(),若按照要求则返回True
判断后几个字符是不是按照要求的 endswith(),若按照要求则返回True
name="alex" #方式一: if name[0:2]=="al": print("是") else: print("否") #方式二: name1=name.startswith('al') print(name1) #判断结尾 name2=name.endswith("ex") print(name2)
格式化format()
#name="我叫{0},今年{1}岁".format("王荣瑞",27) name="我叫{0},今年{1}岁" name1=name.format("王荣瑞",27) print(name1)
编码encode()
name="王帅哥" #解释器读取到内存以后,按照unicode编码存储:12个字节 v1=name.encode("utf-8") print(v1) #按照utf-8存储为9个字节 v2=name.encode("gbk") print(v2) #按照gbk存储为6个字节
循环每个元素,并在元素和元素之间加入连接符 join()
name="alex" #转化为a_l_e_x result="_".join(name) #以"_"作为连接name print(result)
特性:字符串是元素不可变,所以字符元素不能修改和删除
*华丽的分割符
以下是一些不太常用的字符串的方法
casefold() 也是将字符串转换成小写,而且功能更加强大,可以将法语、拉丁语等语言的大写转换成小写
isupper() / islower 判断字符串是否全部是大写或者小写
capitalize() 首字母变大写
name="apple" new_name=name.capitalize() print(new_name) #Apple 首字母变成大写
center() 居中
v="pear" v1=v.center(20,"*") print(v1) #********pear******** 总共20个字符,正中间的是字符串v
ljust() / rjust() 与center的功能类似,只不过是将字符放到最左边和最右边的区别
zfill() 打印一定数量的0,并将字符串放到末尾,0的数量+字符串的数量=括号内的数量
v="apple" v1=v.zfill(20) print(v1) #000000000000000apple
count() 计算子序列出现的次数
v="apple" v1=v.count("") print(v1) #2 p的个数为2个
find() 找索引的位置,存在则返回索引的位置,不存在则返回-1
v="apple" index=v.find("p") print(index) #1 从左到右寻找第一个p的索引位置
index() 也是找索引的位置,存在返回索引的位置,不存在报错,见第十三章(2)
format_map() 以字典的形式进行的字符串格式化
v="我是{0},我最喜欢{1}".format("帅哥","打豆豆") v1="我是{x1},我最喜欢{x2}".format_map({"x1":"帅哥","x2":"打豆豆"}) #需要对应键的值
isalnum() 判断是否是字母或者数字
isalpha() 判断是否是字母
isprintable() 判断是否能打印出来,如空格、换行就不能打印
v1="aaa " print(v1.isprintable()) #False
isspace() 判断是否是空白
istitle() 是否英文单词首字母全部都是大写的
v="Apple Is Good" print(v.istitle()) #True
title() 将所有的英文单词首字母大写
swapcase() 大写变小写,小写变大写
maketrans() 与 translate() 的结合使用
x="12345" y="aeiou" table=str.maketrans(y,x) v="haseiaioshuloiyu" result=v.translate(table) print(result) #h1s23134sh5l43y5 将y中的字母与x的数字联系到一起,并对v字符串进行替换
华丽的分割线
3.3.2能使用的公共的功能
索引,获取一个字符
切片,获取一段字符串(子序列) [ : ]
长度,获取字符长度 len()
步长,在切片的基础上加上一定的字符长度 [ : : ]
name="abcdefg" v1=name[0:-1:2] #设置步长为2 print(v1) v2=name[-1:0:-1] #设置步长为-1,翻转字符 print(v2)
for 循环
3.3.3强制转换成字符串
强制转换
- str(999) #"999"
- str(True) #"True"
- str(["apple","pear"]) #强制转换会转换为"["apple","pear"]"
所以其强制转化为字符串最好用v1="".join(["apple","pear"])
3.3.4字符串格式化
#字符串格式化补充
msg1="我是%s,年龄%s"%("apple",123) #只能用元组,不能用列表
print(msg1) #我是apple,年龄123
msg2="我是%(n1)s,年龄%(n2)s"%{"n1":"apple","n2":666}
print(msg2) #我是apple,年龄666
msg3="我是{0},年龄{1}".format("apple",888) #位置传参
#msg3="我是{0},年龄{1}".format(*("apple",888))
print(msg3) #我是apple,年龄888
msg4="我是{name},年龄{age}".format(name="apple",age=0) #关键字传参
#msg4="我是{name},年龄{age}".format(**{name="apple",age=0})
print(msg4) #我是apple,年龄0
3.3.5 补充:转义符
print("
") #打印出换行
print("\n") #打印
print("\\n") #打印\n
print(r"\n") #打印\n
print(r"
") #打印
#正则表达式中的转义符在python字符串中也刚好有转义的作用
#但是正则表达式中的转义符和字符串中的转义符并没有关系
#且还容易冲突
#为了避免这种冲突
#我们所有的正则都以在工具中测试为结果
#然后只需要在正则表达式和待匹配的字符串外面加上r即可
3.4列表(list)
常用于表示多个事物
3.4.1列表独有的功能
独有的方法 append/insert/pop/remove/clear/extend
在列表的最后追加一个元素 append()
#append() #列表的添加 users=[] while True: name=input("请输入姓名:") users.append(name) print(users)
#录入用户和密码 users=[] for i in range(0,3): usr=input("请输入用户名和密码:(格式为'xxx,xxx')") users.append(usr) #得到一个列表['aaa,123', 'bbb,231', 'ccc,321'] print(users) #用户名和密码校验 usr_name=input("请输入用户名:") usr_password=input("请输入密码:") for i in users: #第一个得到的是 "aaa,123" result=i.split(",") #根据","划分账号和密码 if result[0]==usr_name and result[1]==usr_password: print("登录成功!") break
在指定的索引位置进行插入 insert()
users=["小铁匠","安徒恩","哥布林","阿修罗"] users.insert(0,"普雷") print(users) #['普雷', '小铁匠', '安徒恩', '哥布林', '阿修罗']
删除列表第一个指定的字符串 remove() ,不存在会报错
#删除列表中的元素 #remove() users=["小铁匠","安徒恩","哥布林","阿修罗","哥布林"] users.remove("哥布林") #只能找到第一个删除 print(users) #['小铁匠', '安徒恩', '阿修罗', '哥布林']
删除指定位置的字符串,不加指定位置则删除最后一位 pop()
users=["小铁匠","安徒恩","哥布林","阿修罗","哥布林"] users.pop(2) print(users) #['小铁匠', '安徒恩', '阿修罗', '哥布林'] #pop不加任何东西表示默认删除最后一位 users.pop() print(users) #['小铁匠', '安徒恩', '阿修罗']
补充: new=pop(0) 可以将删除的值赋值给一个值保存起来
清空列表 clear()
users=["小铁匠","安徒恩","哥布林","阿修罗","哥布林"] users.clear() print(users) #[]
将另一个列表的值添加到本列表中 extend()
new1=["one","two","three"] new2=["four","five","six"] new1.extend(new2) print(new1) #['one', 'two', 'three', 'four', 'five', 'six']
注意:元组没有extend()方法
#extend()方法再解析 #列表有extend()方法,元组也可以添加到列表中 #元组没有extend()方法 new1=["one","two","three"] new2=("four","five","six") new3=("one","two","three") new1.extend(new2) #元组可以循环添加到列表中 print(new1) #['one', 'two', 'three', 'four', 'five', 'six'] #new2.extend(new3) #报错 #print(new2) #'tuple' object has no attribute 'extend' new1.extend(new1) print(new1)
reverse(),反转
v1=[33,22,11,55,44] v1.reverse() print(v1)
sort(),排序
v1=[33,22,11,55,44] v1.sort() print(v1) #[11, 22, 33, 44, 55]由小到大 v1.sort(reverse=False) print(v1) #[11, 22, 33, 44, 55]由小到大 v1.sort(reverse=True) print(v1) #[55, 44, 33, 22, 11]由大到小
小结
增:
- append/insert
删
- remove/pop/del user[0]
改
- user[3] = "修改"
查
- 切片/索引
列表的嵌套
user=["小铁匠","安徒恩",["赛利亚",["卢克"]],"哥布林","阿修罗","哥布林"] user[0] #"小铁匠" user[0][2] #"匠" user[2] #["赛利亚",["卢克"]] user[2][0] #"赛利亚" user[2][2] #["卢克"] user[2][2][0] #"卢克" user[2][2][0][1] #"克" user[2][2][0][-1]#"克"
3.4.2能使用的公共的功能
len,记录长度按","分割
usr_len=len(usr) print(usr_len) #4
索引
切片
步长
#实现一个整数加法计算器(两个数相加)
#如:content=input("请输入内容:"),用户输入5+9或5+ 9或5 + 9(含空白)
#然后进行分割转换最终进行整数的计算得到结果
message=input("请输入内容:")
cal=message.split("+") #形成列表
cal_first=int(cal[0].strip()) #列表中前一个数去除空格,转化为整型
cal_second=int(cal[1].strip()) #列表中后一个数去除空格,转化为整型
total=cal_first+cal_second
print("%s结果为%d"%(message,total))
for循环
user=["小铁匠","安徒恩","哥布林","阿修罗"] for i in user: #第一次大循环,i="小铁匠" print(i) for ele in i: #第一次小循环,以i为元素, ele="小" print(ele)
删除(数字/布尔类型/字符串除外)
user=["小铁匠","安徒恩","哥布林","阿修罗"] del user[0] print(user) #['安徒恩', '哥布林', '阿修罗']
注意:字符串本身不能修改或者删除,如name="alex",del name[1]会报错
列表是可变类型
修改 (数字/布尔类型/字符串除外)
user=["小铁匠","安徒恩","哥布林","阿修罗"] user[1]="哥布林" print(user) #["小铁匠","哥布林","哥布林","阿修罗"] #user[0][1]="修" 会报错
3.4.3强制转换成列表
- list("asdsadsaf") #["a", "s", "d", ...]
- list((1,2,3)) #[1,2,3] 元组转化成列表
3.5元组(tuple)
元组的书写规范(创建以后并不能修改其中的元素)
#书写规范
user=[11,22,"你好"] #列表(可变)
users=(11,22,"你好") #元组(不可变)
print(users)
但是需要分辩是否是修改了元组中的值
v1=(11,22,33)
#v1[1]=999 错误
v1=99 #正确,没有修改元素的值
3.5.1元组独有的功能
近似可以看成无
3.5.2能使用的公共功能
索引(排除:int/bool)
users=(11,22,"你好") print(users[2]) #"你好"
步长(排除:int/bool)
切片(排除:int/bool)
只是 生成一个新的值
删除(排除:str/int/bool/tuple)
修改(排除:str/int/bool/tuple)
for(排除:int/bool)
len(排除:int/bool)
3.5.3强制转换成元组
- tuple("asdasfsd") #强制转换为元组("a", "s",...)
- tuple([1,2,3]) #列表转换为元组(1,2,3)
3.6字典(dict)
帮助用户表示一个事物的多种信息,需要注意:之前的列表和元组是有序的,字典是无序的(py3.6以后字典是有序的)
info={"name":"pig","age":18,"hobby":"chess"} #冒号前面为键,后面为值
print(info["name"]) #pig
print(type(info)) #<class 'dict'>
print(type(info["age"])) #<class 'int'>
3.6.1字典独有的功能
keys()获取所有的键
info={"name":"pig","age":18,"hobby":"chess"} for item in info.keys(): print(item)
values()获取所有的值
info={"name":"pig","age":18,"hobby":"chess"} for item in info.values(): peint(item)
items()获取所有的键值
info={"name":"pig","age":18,"hobby":"chess"} #冒号前面为键,后面为值 v1=info.keys() #获取字典中所有键 v2=info.values() #获取字典中的所有值 print(v1) #dict_keys(['name', 'age', 'hobby']) print(v2) #dict_values(['pig', 18, 'chess']) for v3,v4 in info.items(): print(v3,v4) #打印所有的键值 #name pig #age 18 #hobby chess
get(),获取对应键的值,并且解决查询的键不存在的报错问题
info={"k1":"v1","k2":"v2"} #print(info["k111"]) #会报错KeyError: 'k111' value=info.get("k11111") print(value) #当键不存在的时候返回None,None其实就是python中的空 value1=info.get("k11111",666) print(value1) #当键不存在的时候返回666
删除pop()/del
info={"k1":"v1","k2":"v2"} result=info.pop("k2") print(info,result) #{'k1': 'v1'} v2 del info["k1"] print(info) #{} info={"k1":"c1","k1":"c2"} result=info.pop("k1") print(info,result) #全部包含"k1"的键值都删除{} c2 info={"k1":"c1","k1":"c2"} del info["k1"] print(info) #包含"k1"的 键值都删除{}
update()
info={"k1":"v1","k2":"v2"} #放一个不存在的值是添加 info.update({"k3":"v3","k4":"v4"}) print(info) #{'k1': 'v1', 'k2': 'v2', 'k3': 'v3', 'k4': 'v4'} #放一个存在的值是更新(覆盖) info.update({"k2":"666"}) print(info) #{'k1': 'v1', 'k2': '666', 'k3': 'v3', 'k4': 'v4'}
3.6.2能使用的公共功能
len 有多少个键值就为多少
索引
info={"name":"pig","age":18,"hobby":"chess"} info['name'] info['age']
切片(无)
步长(无)
for
主要还是通过keys() / values() /items()
#一个报错的栗子 info={"name":"pig","age":18,"hobby":"chess"} for item,v in info: print(item,v) #ValueError: too many values to unpack (expected 2)
#加深对于items()的理解 info={"name":"pig","age":18,"hobby":"chess"} for i in info.items(): print(i) #此时并不会报错 #('name', 'pig') #('age', 18) #('hobby', 'chess') #其实类似 v="1+3" result=v.split("+") print(result) #['1', '3'] print(type(result)) #分割以后是列表<class 'list'> #可以用result[0]和result[1]来表示 a,b=v.split("+") #把1赋值给a,3赋值给b print(type(a)) #<class 'str'> print(a,b) #1 3 #同理元组和列表也可以这样进行取值 c,d=[1,3] print(c,d) #1 3 e,f=(1,3,) print(e,f) #1 3
修改
#修改值 info={"name":"pig","age":18,"hobby":"chess"} info['name']="duck" print(info) #{'name': 'duck', 'age': 18, 'hobby': 'chess'}
#修改键 #删除后再增加 info={"name":"pig","age":18,"hobby":"chess"} del info['hobby'] #若字典中没有这样一个键的时候,会添加这样一个键和值 info['play']='chess' #{'name': 'pig', 'age': 18, 'play': 'chess'}
删除
#删除的时候,键和值是一个整体 info={"name":"pig","age":18,"hobby":"chess"} del info['name'] print(info) #{'age': 18, 'hobby': 'chess'}
3.6.3强制转换成字典
好像还没见到过
v="aaahuds"
#print(dict(v)) #dictionary update sequence element #0 has length 1; 2 is required 报错
v1="hhhh"
print(dict({v:v1})) #{'aaahuds': 'hhhh'} 还是需要按照字典的格式进行转换
3.6.4有序字典
#有序字典
from collections import OrderedDict #按ctrl点击OrderedDict可以查看其中的方法
info=OrderedDict()
info["k1"]=123
info["k2"]=456
#循环 打印一定先打印k1,后打印k2
for item,key in info.items():
print(item,key)
# k1 123
# k2 456
补充:
print("示例一:")
li=["李杰","李女神","猪猪","李连杰"]
for item in li:
print(item)
if item.startswith("李"):
li.remove(item)
print("****************")
print(li) #['李女神', '猪猪']
print("示例二:")
li=["李杰","李女神","猪猪","李连杰"]
for i in range(len(li)-1,-1,-1): #从后往前取
print(li[i])
if li[i].startswith("李"):
li.remove(li[i])
print("***************")
print(li)
3.7集合(set)
列表/字典/集合 不能做集合的元素
v={}
print(type(v)) #空字典<class 'dict'>
v1=set()
print(type(v1)) #空集合<clss 'set'>
v3={1,2,3,4} #非空的集合
3.7.1集合独有的功能
独有的功能(字典是无序的,且没有重复值)
add()增加
v={1,2} v.add("李韶奇") print(v) #{1, 2, '李韶奇'} v.add("李韶奇") print(v) #{1, 2, '李韶奇'}
discard()删除,没有索引的删除
v={1,2,"李韶奇"} v.discard("李韶奇") print(v) #{1, 2}
remove()删除,不存在就会报错
v={1,2} v.remove(0) print(v) #报错,KeyError: 0
update(),可以批量添加
v={11,22,3,} v.update({"里塞奇",33}) #相当于批量增加 print(v) #{33, 3, 22, 11, '里塞奇'}
交集intersection()
v={1,2,"韶奇"} v.intersection({1,"韶奇"}) print(v) #{1, 2, '韶奇'} #可以看出 intersection并不改变其原来的集合,需要生成新的值 v1=v.intersection({1,"韶奇"}) print(v1) #{1, '韶奇'} #注意,intersection()后面也可以用列表
并集union()
v={1,2,"apple"} v1=v.union({1,2,"pear"}) print(v1) #{1, 2, 'pear', 'apple'}
差集difference()
v1={1,2,"apple"} v2={1,2,"pear"} v3=v1.difference(v2) #在集合v1中有,而v2中没有的元素 print(v3) #{"apple"} v4=v2.difference(v1) #在结合v2中有,而v1中没有的元素 print(v4) #{"pear"}
对称差集symmetric_difference()
v1={1,2,"apple"} result=v1.symmetric_difference({1,2,"pear"}) print(result) #{'apple', 'pear'}
3.7.2能使用的公共功能
公共的方法
len
for循环
v={1,2,"apple"} for item in v: print(item)
集合的嵌套
#列表/字典/集合 不能放在集合中,不能作为字典的key(unhashable)
哈希是什么?内部为了查找的方便,会将值进行哈希算法得到一个值(对应内存地址),用于快速查找
集合的特殊情况
v1={1,"True"} print(v1) #{1, 'True'} v2={1,True} print(v2) #{1} v3={1,False} print(v3) #{False, 1}
3.7.3强制转换成集合
v0="abacde"
print(set(v0)) #{'d', 'c', 'b', 'e', 'a'} #对于重复的单个字符串不会再添加到集合中
v=[1,2,3,4]
print(set(v)) #{1, 2, 3, 4} #列表转换成集合
v1=(1,2,3,4)
print(set(v1)) #{1, 2, 3, 4} #元组转换成集合
v2={"k1":"apple","k2":"pear"}
print(set(v2)) #{'k2', 'k1'} 将键转换成集合的元素
3.8嵌套问题
3.8.1列表和元组的嵌套
v2=[11,22,33,(11,22,33)]
v2[-1][1]=99 #错误,元组中的元素不能修改
v2[-1]=123 #正确
v3=(11,22,33,[11,22,33])
v[-1]=123 #错误,列表是元组的元素,不能修改
v[-1][2]=99 #正确,列表中的值可以修改
3.8.2字典的嵌套
info={
"k1":"v1", #值可以嵌套字符串
"k2":True, #值可以嵌套布尔类型
"k3":1, #值可以嵌套整型
"k4":[1,2,3],#值可以嵌套列表
"k5":(1,2,3),#值可以嵌套元组
"k6":{"kk":"vv"}, #值可以嵌套字典
#所有的数据类型都可以当字典的值
1:{"kk":"vv"}, #整型可以当键
False:{"kk":"vv"}, #布尔值可以当键
"你好胖":{"kk":"vv"}, #字符串可以当键
(1,2,3):{"kk":"vv"}, #元组可以当键
#列表和字典不可以当键,会产生TypeError: unhashable type: 'list'
#表示列表和字典类型不可哈希
#[1,2,3]:{"kk":"vv"}, #列表不可以当键
#{1,2,3}:{"kk":"vv"} #字典不可以当键
#由于这两个数据类型是可变类型,哈希函数不可放可变的数据类型
}
print(info)
#{'k1': 'v1', 'k2': True, 'k3': 1, 'k4': [1, 2, 3], 'k5': (1, 2, 3), 'k6': {'kk': 'vv'},
#1: {'kk': 'vv'}, False: {'kk': 'vv'}, '你好胖': {'kk': 'vv'}, (1, 2, 3): {'kk': 'vv'}}
#嵌套后的取值
#data=[1,2,{"k1":1,"k2":2,"k3":(11,22,33),"k4":[1,(12,3,4)]},3]
#想取到数值12
data=[1,2,{"k1":1,"k2":2,"k3":(11,22,33),"k4":[1,(12,3,4)]},3]
num=data[2]["k4"][1][0]
print(num)
#想在字典中的列表中第一个位置插入9
data[2]["k4"].insert(0,9)
print(data) #[1, 2, {'k1': 1, 'k2': 2, 'k3': (11, 22, 33), 'k4': [9, 1, (12, 3, 4)]}, 3]
3.9各种数据类型为空的情况
#None
v1=int()
print(v1) #0
v2=bool()
print(v2) #False
v3=""
v4=str()
print(v3,v4) #空字符串
v5=[]
v6=list()
print(v5,v6) #空列表[] []
v7=()
v8=tuple()
print(v7,v8) #空元组() ()
v9={}
v10=dict()
print(v9,v10) #空字典{} {}
v11=set()
print(v11) #空集合 set()
3.10列表、元组、字典、集合的区别和特征
- 元组:对象有序排列,通过索引读取读取,对象不可变。
- 列表:对象有序排列,通过索引读取读取,对象是可变的。
- 字典:对象的无序集合,通过键值(key-value)读取,可变的,键唯一,且不可变,值可变,可以任意嵌套
列表 | 元组 | 字典 | 集合 | |
---|---|---|---|---|
是否可变 | 是 | 否,元组不可变 | 是 | 是 |
索引 | 下标 | 下标 | 键值对 | 值,不会重复,唯一 |
是否有重复值 | 有重复值 | 有重复值 | 有重复值 | 无重复值 |
是否有序 | 有序 | 有序 | 无序 | 虚无 |