一、输入输出函数(input、print)
1、输入(input)
作用:接收来自用户的输入
返回值类型:输入值的类型为str
值的存储:使用=对输入的值进行存储
Eg1:
present = input(‘六一想要什么礼物呢?’)#在控制台输入值
print(present)
Eg2:
#从键盘录入两个整数,计算两个整数的和\
a=int(input('请输入一个加数:'))\
b=int(input('请输入另一个加数:'))\
print(a+b)
2、输出(print)
1. #可以输出 数字
print(520)
2. # 可以输出 字符串
print('Python')
3. # 含有运算符的 表达式
print(3*2)
4.
# 将数据输出文件中,注意点:1. 所指定的盘符存在 2. 使用file=fp将数据输入
fp=open('E:/text.txt','a+')#a+如果文件不存在就创建,存在就在文件内容后面追加
print('hello world',file=fp)
fp.close()
5. # 不进行换行输出(输出内容在一行显示) print('hello','world','python')
二、转义字符
1. # 转义字符 : \ + 转义功能的首字母\
print('hello\nworld')# n—>newline 的首字符表示换行\
print('hello\tworld') # t—>tab 制表符,占 4位,从前往后一次占,\t 不足 4 位就用空隔代替 \
print('helloooo\tworld')\
print('hello\rworld')#r—>return 回车 ,后面的内容会把前面的覆盖掉\
print('hello\bworld')#b—>backspace 退格,回退一个字符\
print('http:\\\\www.baidu.com')#\\反斜杠\
print('老师说:\“大家好\”,\'大家好\'')#\',\",单引号,双引号\
2. 原字符:不希望字符串中的转义字符起作用,就使用原字符,就是在字符串之前加上r,或R
print(r'hello\nworld')
#注意事项,最后一个字符不能是反斜杠\
#print(r'hello\nworld\')
三、二进制与字符编码
四、python中的标识符与保留字
1. 保留字(命名时无法使用)
#可以输出有哪些保留字*
import keyword
print(keyword.kwlist)
2. 标识符(给变量、函数、类、模块和其它对象起的名字)
规则:
-
字母、数字、下划线
-
不能以数字开头
-
不能是保留字
-
严格区分大小写
五、Python中的变量与数据类型
1. 变量(标识+类型+值)
-
标识: 表示对象所存储的内存地址,使用内置函数id(obj)来获取
-
类型:表示的是对象的数据类型,使用**内置函数type(obj)**来获取
-
值:表示对象所存储的具体数据,用print(obj)可以将值进行打印输出
#变量
name='Krystal'
print(name)
print('标识',id(name))
print('类型',type(name))
print('值',name)
结果:
标识 1782136168752
类型 <class 'str'>
值 Krystal
2.数据类型
常用数据类型:
- 整型—>int—>98
- 浮点型—>float—>3.14159
- 布尔类型—>bool—>true、false
- 字符串类型—>str—>’人生苦短,我用Python’
#整数类型
#可以表示:正数、负数、0
n1=90
n2=-90
n3=0
print(n1,n2,n3,type(n3))
#整数可以表示为二进制,十进制(0b),八进制(0o),十八进制
print('十进制',118)
print('二进制',0b10101001)
print('八进制',0o176)
print('十六进制',0x193E)
#浮点数 有时不准确
a1=1.1
a2=2.2
a3=2.3
print(a1+a2)
print(a1+a3)
from decimal import Decimal
print(Decimal('1.1')+Decimal('2.2'))
#布尔类型 True->1,False->0
print(type(True))
print(True+1)
print(False+1)
#字符串类型 (三种:单引号:’‘,双引号:”“,三引号(可分布在连续的多行):''' '''/""" """)
str1='人生苦短,我用Python'
str2="人生苦短,我用Python"
str3="""人生苦短,我用Python"""
str4="""人生苦短
我用Python"""
print(str1,type(str1))
print(str2,type(str2))
print(str3,type(str3))
print(str4,type(str4))
3.数据类型间的转换
str():将其它类型转为字符型
int(): 将其它数据类型转为整数
float(): 将其它类型转为浮点类型
4.注释
-
单行注释:#
-
多行注释:'''内容'''
-
中文编码声明注释:在文件开头加上中文声明注释,用以指定源码文件的编码格式 :#coding:gbk/UTF-8等
六、python中的运算符
1. 算术运算符:+、-、*、/、//、%、**
#加减乘除
print(1+1)
print(1-1)
print(1*1)
print(1/1)
print(11/2)# 除法运算
print(11//2)# 5 整除运算
print(11%2)# 1 取余运算
print(2**2)# 2的2次方
print(2**3)# 2的3次方
2. 赋值运算符:=、+=、-=、*=、/=、//=、%=
#赋值运算符,运算顺序从右往左
#支持链式赋值 a=b=c=20
a=b=c=20
print(a,id(a))
print(b,id(b))
print(c,id(c))
#支持参数赋值 +=,-=,*=,/=,//=,%=
print('-----------支持参数赋值------')
d=10
e=d%13
print(e,type(e))\
#支持系列解包赋值 a,b,c=20,30,40
print('-----------支持系列解包赋值————------')
a,b,c=20,30,40
print(a,b,c)
print('-----------交换两个变量值————------')
a,b=10,20
print('交换之前:',a,b)
#交换
a,b=b,a
print('交换之后:',a,b)
3. 比较运算符:>、<、>=、<=、==
比较对象的标识使用 is
比较对象的值用==
#比较运算符 结果为true或false
a,b=10,20
print('a>b吗?',a>b)#false
print('a<b吗?',a<b)#true
print('a>=b吗?',a>=b)#false
print('a<=b吗?',a<=b)#true
print('a==b吗?',a==b)#false
#比较对象的标识使用 is ;比较对象的值用==
a,b=10,10
print(a is b) #true 说明a和b的标识相等
print(a == b) #true 说明a和b的id值相等
#一下代码未学过,以后会讲解
list1=[11,22,33,44]
list2=[11,22,33,44]
print(list1==list2)#true
print(list1 is list2) #false list1和2的id标识不相等
print(list1 is not list2)#true list1和2的id标识相等
4. 布尔运算符:and、or、not、in、not in
#布尔运算符 and(并且)、or(或)、not(非)、 in 与 not in 是否存在
a,b=1,2
#and 当两个运算数都为true,运算结果才为true
print(a==1 and b==2)#true
print(a!=1 and b==2)#false
#or 当一个运算数都为true,运算结果才为true
print(a==1 or b==2)#true
print(a!=1 or b==2)#true
#not 对bool类型的操作数取反
f=True
print(not f)#false
# in 与 not in 是否存在
s='helloworld'
print('h' in s)#true
print('h'not in s)#false
5. 位运算符:&、|、<<、>>
print(4&8)#按位与&,同1时结果为1
print(4|8)#按位或|,同为0时结果为0
print(4<<1)#向左移动1位(高位截断,低位补0),相当于乘以2
print(4<<2)#向左移动2位(高位截断,低位补0),相当于乘以4
print(4>>1)#向右移动1位(低位截断,高位补0),除以2
print(4>>2)#向右移动2位(低位截断,高位补0),除以4
6. 运算符优先级
()>算术运算符>位运算符>比较运算符>布尔运算符>赋值运算符
总结一(一到六)
七、程序的组织结构
1. 顺序结构
#把大象装冰箱
print('--------程序开始-------')
print('1.把冰箱打开')
print('2.把大象装进去')
print('3.把冰箱关闭')
print('--------程序结束-------')
2. 选择结构
① 单分支if结构
if 条件表达式:
条件执行体
② 双分支if...else结构
if 条件表达式:
条件执行体1
else:
条件执行体2
money=1000 #余额
s=int(input('请输入取款金额:')) #取款金额
#判断余额是否够
if money>=s:
money=money-s
print('取款成功,余额为:',money)
else:
print('余额不足');
③ 多分支if...elif...else结构
if 条件表达式1:
条件执行体1
elif 条件表达式2:
条件执行体2
elif 条件表达式N:
条件执行体N
[else:]
条件执行体N+1
'''
多分支结构,多选一执行
从键盘录入一个整数 成绩
90-100 A
80-89 B
70-79 C
60-69 D
0-59 E
其余为非法数据(非成绩有效范围)
'''
score=int(input('请输入成绩:'))
if score>=90 and score<=100:
print('A')
elif score>=80 and score<=89:
print('B')
elif 70<=score<=79:
print('C')
elif score>=60 and score<=69:
print('D')
else:
print('非成绩有效范围')
④ if语句的嵌套
if 条件表达式1:
if 内层条件表达式:
内层条件执行体1
else :
内层条件执行体2
else: 条件执行体1
member=input('您是会员吗?y/n')
money=int(input('消费金额:'))
if member=='y':
if money>200:
print('会员九折,花费金额为:',money*0.9)
elif money>100:
print('会员八五折,花费金额为:',money*0.85)
else:
print("此次消费金额较低,不打折")
else:
if money>200:
print('非会员打九五折,花费金额为:',money*0.95)
else:
print('非会员消费金额较低,不打折')
⑤条件表达式
是if...else...的简写
语法结构:x if 判断条件 else y
运算规则:如果判断条件的值为true,执行x,否则执行y
'''从键盘输入两个整数,比较两个整数的大小'''
a=int(input('请输入第一个整数:'))
b=int(input('请输入第二个整数:'))
print('使用条件表达式进入比较')
print( str(a)+'大于等于'+str(b) if a>b else str(a)+'小于'+str(b))
3. 循环结构
① while循环
语法结构:
while 条件表达式:
条件循环体
选择结构的if与循环结构的while区别:
-
if是判断一次,条件为true执行一次
-
while是判断N+1次,条件为true执行N次
Eg:
a=1
while a<10:
print(a)
a+=1
Eg:
#计算1到100间的偶数和
'''初始化变量'''
num=0
a=1
'''条件判断'''
while a<=100:
'''条件执行体(求和)'''
if a%2==0: #判断是否是偶数 ===>if not bool(a%2):
if bool(a%2):#判断是奇数
num+=a
'''改变变量'''
a+=1
print('1到100间的偶数和为:',num)
② for——in循环
for-in遍历的对象必须是可迭代对象,in表达从(字符串、序列等)中依次取值,又称遍历
语法结构:
for 自定义的变量 in 可迭代对象:
循环体
循环体内不需要访问自定义变量,可以将自定义变量替代为下划线
**Eg:******
for i in 'python':
print(i)
for i in range(10):
print(i)
#如果在循环体中不需要使用自定义变量,可将自定义变量写为"_"
for _ in range(3):
print('人生苦短,我用python')
print("使用for循环,计算1到100间的偶数和")
sum=0
for i in range(1,101):
if not bool(i%2):
sum+=i
print('1到100间的偶数和为:',sum)
4. 嵌套循环
'''
输出一个三行四列的矩形
'''
for i in range(1,4):
for j in range(1,5):
print('*',end='\t')#不换行输出
print() #换行
'''
打印九九乘法表的格式
'''
for i in range(1,10):
for j in range(1,i+1):\
print(str(j)+'x'+str(i)+'='+str(i*j),end='\t')\
print()
二重循环中的break和continue:
or i in range(5):
for j in range(1,11):
if j%2==0:
break
print(j)
结果为5个1
for i in range(5):
for j in range(1,11):
if j%2==0:
continue
print(j,end='\t')
print()
结果为5行 1 3 5 7 9
5. break、continue、else语句
- break语句:用于结束循环结构,通常与分支结构if联合使用。
Eg:
'''
从键盘录入3个数,如果正确就结束循环
'''
for i in range(3):
pwd=input('请输入密码:')
if pwd=='888':
print('密码正确!')
break
else:
print('密码错误!')
'''使用while'''
a=0
while a<3:
pwd=input('请输入密码:')
if pwd=='123':
print('密码正确')
break
else:
print('密码错误')
a+=1
- continue语句:用于结束当前循环,进入下一次循环,常与分支结构if一起使用
'''
要求输出1到50间所有5的倍数,5,10,15,25...
使用continue语句
'''
# for i in range(1,51):
# if i%5==0:
# print(i)
print('--------continue语句--------')
for i in range(1,51):
if i%5!=0:
continue
print(i)
- else语句:与else语句配合使用的三种情况
①if不成立执行else:
if ...else...
② 没有碰到break语句时执行else:
while : ... else: ...
for...in :...else: ...
for item in range(3):
pwd=input('请输入密码:')
if pwd=='888':
print('密码正确')
break
else:
print('密码错误')
else:
print('三次密码输入都错误')
----------------------------------------
i=0
while i<3:
pwd=input('请输入密码:')
if pwd=='999':
print('密码正确')
break
else:
print('密码错误')
i+=1
else:
print('三次密码输入都错误')
八、pass语句
pass语句什么都不做,只是一个占位符,用在语法上需要语句的地方
什么时候用: 先搭建语法结构,还没想好代码怎么写的时候
哪些语句一起使用:
if语句的条件执行体
for-in语句的循环体
定义函数时的函数体
Eg:
#pass语句,什么都不做,只是一个占位符,用到需要写语句的地方
a=input('您是会员吗?y/n')
if a=='y':
pass
else:
pass
九、对象布尔值
python一切皆对象,所有对象都有一个布尔值
获取对象的布尔值,使用内置函数bool()
以下对象的布尔值位False:
- false
- 数值0
- None
- 空字符串
- 空列表
- 空元组
- 空字典
- 空集合
其余剩下的对象的布尔值都为true
十、range()函数
用于生成一个整数序列,返回值是一个迭代器对象
创建range对象的三种方式:
- range(stop)——>创建一个(0,stop)间的整数序列,从0开始,步长为1
- range(start,stop)—>创建一个(start,stop)之间的整数序列,从start开始,步长为1
- range(start,stop,step)—>创建一个(start,stop)之间的整数序列,步长为step
range函数的优点:
不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的,因为仅仅需要存储start,stop和step,只有当用到range对象时,才会去计算序列中的相关元素
in与not in判读整数序列中是否存在(不存在)指定的整数
'''第一种方式'''
r=range(10) #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 默认从0开始,步长为1
print(r) #返回值为一个迭代器对象,range(0,10)
print(list(r)) #查看range对象中的值
'''第二种创建方式,'''
r=range(1,10) #指定了起始值,从1开始,到10结束 (不包含10),默认步长1
print(list(r)) #[1, 2, 3, 4, 5, 6, 7, 8, 9]
'''第三种创建方式'''
r=range(1,10,2) #[1,3,5,7,9]
print(list(r))
'''判断指定的整数,在序列中是否存在 in,not in'''
print(10 in r) #false
print(9 in r) #true
print(10 not in r) #true
总结二(七到十)
十一、列表
1. 列表的创建与删除
① 为什么需要列表?
- 变量可以存储一个元素,而列表可以存储多个元素,程序可以方便的对这些数据进行操作。
- 列表相当于其它语言中的数组。
② 列表的创建方式?
- 使用中括号 [ ]
- 使用内置函数 list()
#第一种方式
lst = ['hello','world',98]
#第二种方式
lst2 = list(['hello','world',98])
③ 列表的特点?
- 列表元素有序排列
- 索引映射一个数据
- 列表可存重复数据
- 任意数据类型混存
- 根据需要动态分配和回收内存
2. 列表的查询操作
① 获取列表中指定元素的索引:.index()
- 如果列表中有相同元素只返回列表中相同元素的第一个元素的索引
- 如果查询的元素在列表中不存在,则会抛出valueError
- 还可以在指定的start和stop间进行查找
lst=['hello','world',98,'hello']
print(lst.index('hello'))#0
print(lst.index(98))#2
# print(lst.index('phyton'))#ValueError
print(lst.index('world',0,2))#1
② 根据索引获取列表中的单个元素
- 正向索引从0到N-1。如lst[0]
- 逆向索引从-N到-1. 如lst[-N]
- 指定索引不存在,抛出indexError
lst=['hello','world',98,'hello','world',990]
print(lst[2])#98
print(lst[-1])#990
print(lst[10])#indexError
③ 利用切片获取列表中的多个元素
语法格式:
列表名[start:stop:step]
- 切片结果:原列表片段的拷贝
- 切片范围:[start,stop)
- step默认为1
- step为正数,从start开始往后计算切片
- step为负数,从start开始往前计算切片
lst=[10,20,30,40,50,60,70,80]
#start=1,stop=6,step=1
print(lst[1:6:1])
print('原列表:',id(lst))
lst2=lst[1:6:1]
print('切的片段:',id(lst2))
print(lst[1:7])#默认步长为1
print(lst[1:7:])
print(lst[1:8:2])#步长为2 [20,40,60,80]
print('---------step为正数,从start开始往后计算切片-------')
#stop=6,step=2,start采用默认
print(lst[:8:2])#[10,30,50,70]
#start=1,step=2,stop采用默认
print(lst[1::2])#[20,40,60,80]
print('---------step为负数,从start往前计算切片----------')
print('原列表:',lst)
print(lst[::-1])#倒叙输出
#start=7,stop 省略 step=-1
print(lst[7::-1]) #[80, 70, 60, 50, 40, 30, 20, 10]
print(lst[7:4:-1])#[80,70,60]
④ 判断指定元素在列表中是否存在:in / not in
lst=['hello','world',10,20]
print('hello' in lst)#true
print(30 not in lst)#true
⑤ 列表元素的遍历
语法格式:
for 迭代变量 in 列表名:
操作
print('----迭代变量-----')
for item in lst:
print(item)
3. 列表元素的增、删、改操作
① 列表元素的增加操作
-
append() 在列表的末尾添加一个元素
-
extend() 在列表的末尾至少添加一个元素
-
insert() 在列表的任意位置添加一个元素
-
切片 在列表的任意位置添加至少一个元素
lst=[10,20,30]
print('添加元素之前:',lst,id(lst))#[10, 20, 30] 1923779784448
lst.append(99)
print('append添加元素之后:',lst,id(lst))#[10, 20, 30, 99] 1923779784448
lst2=[88,99,90]
lst.extend(lst2)
print('extend添加元素之后:',lst)# [10, 20, 30, 99, 88, 99, 90]
lst.insert(0,90)
print('任意位置insert添加元素之后:',lst)# [90, 10, 20, 30, 99, 88, 99, 90]
lst3=[True,False,'HELLO']
#在任意位置上添加N多个元素
lst[2:]=lst3
print(lst)#[90, 10, True, False, 'HELLO']
② 列表元素的删除操作
- remove() 一次删除一个元素、重复元素只删除第一个、元素不存在抛出valueError
- pop() 删除一个指定索引位置上的元素、指定索引不存在抛出IndexError、不指定索引,默认删除最后一个元素
- 切片 一次至少删除一个元素
- clear() 清空列表
- del 列表名 删除列表
lst=[10,20,30,40,50,60,30]
lst.remove(30)#重复删除第一个元素
print(lst) #[10, 20, 40, 50, 60, 30]
#pop()根据索引移除元素
lst.pop(1)
print(lst)#[10, 40, 50, 60, 30]
# lst.pop(5)#指定索引不存在,将抛出异常
lst.pop()#如果不指定索引,将删除最后一个参数
print(lst)#[10, 40, 50, 60]
print('-----切片操作--删除至少一个元素,将产生一个新的列表对象----')
new_list=lst[1:3]
print('原列表:',lst,id(lst))#[10, 40, 50, 60] 2034521272064
print('新列表:',new_list,id(new_list))#[40, 50] 2034521596288
'''不产生新列表'''
lst[1:3]=[]
print(lst,id(lst))#[10, 60] 2034521272064
'''clear清空列表中的所有元素'''
lst.clear()
print(lst) #[]
'''del语句将列表对象删除'''
del lst
#print(lst)#NameError: name 'lst' is not defined
③ 列表元素的修改
- 为指定索引的元素赋予一个新值
- 为指定的切片赋予一个新值
lst=[10,20,30,40]
#一次修改一个值
lst[2]=100
print(lst)#[10, 20, 100, 40]
#利用切片,一次修改多个值
lst[1:3]=[100,200,300]
print(lst)#[10, 100, 200, 300, 40]
4. 列表元素的排序
常见的两种方式:
- 调用sort()方法,列表中所有元素默认按照从小到大的顺序进行升序排序,reverse=Fale,进行升序排序,可以指定一个关键字reverse=True,进行降序排序
- 调用内置函数sorted(),可以指定reverse=True,进行降序排序,原列表不发生变化
lst=[10,2,45,69]
print('排序前列表:',lst,id(lst))#[10, 2, 45, 69] 2485313990336
lst.sort()
print('排序后列表:',lst,id(lst))#[2, 10, 45, 69] 2485313990336
#通过指定关键字参数,将列表中的元素进行降序排序
lst.sort(reverse=True)
print(lst)#[69, 45, 10, 2]
lst.sort(reverse=False)
print(lst)#升序排列 [2, 10, 45, 69]
lst=[22,11,44,66]
print('原列表:',lst)#[22, 11, 44, 66]
#开始排序
new_list=sorted(lst)
print(lst)#[22, 11, 44, 66]
print(new_list)#[11, 22, 44, 66]
#指定关键字参数,实现列表元素的降序排序,默认为升序
desc_list=sorted(lst,reverse=True)
print(desc_list) #[66, 44, 22, 11]
5. 列表生成式
生成列表的公式,语法格式:
[i * i for i in range(1,10)]
lst=[i*i for i in range(1,10)]
print(lst)# [1, 4, 9, 16, 25, 36, 49, 64, 81]
'''列表中的元素值为2,4,6,8,10'''
lst2=[i*2 for i in range(1,6)]
print(lst2) #[2, 4, 6, 8, 10]
总结:
十二、字典
1. 什么是字典。{}
-
python内置的数据结构之一,与列表一样是一个可变序列(可执行增删改查操作:列表、字典),反之不可变序列如int、str
-
以键值对’key’:value的方式存储数据,字典是一个无序的序列
scores = { ‘张三’:100, ‘李四’:98, }
注意:
- 字典是根据hash(key)函数进行分配,并不是有序分配
- 要求key为不可变序列,才能使得hash函数计算出来不改变。
2. 字典的原理
字典是根据key查找value所在的位置
3. 字典的创建
字典的创建:
- 使用花括号{ }
- 使用内置函数 dict()
'''字典的创建方式'''
#使用{}
scores={'李四':90,'王五':80,'张三':100}
print(scores)#{'李四': 90, '王五': 80, '张三': 100}
print(type(scores))#<class 'dict'>
#创建dict()
student=dict(name='lisa',age=23)
print(student)#{'name': 'lisa', 'age': 23}
#创建空字典
d={}
print(d)#{}
4. 字典的查询操作
字典中获取value:
- [key]—— eg:scores["张三"]
- get(key)方法——eg:scores.get("张三")
区别:
·[ ]如果字典中不存在指定的key,抛出keyError异常 ·get()方法,如果不存在指定的key,则返回None,可以通过参数设置默认的value,以便指定的key不存在时返回
'''获取字典的元素'''
scores={'lisa':100,'krystal':200}
'''第一种方式,使用[]'''
print(scores['lisa']) #100
# print(scores['xiao']) #KeyError
'''第二种方式,使用get()方法'''
print(scores.get('krystal'))#200
print(scores.get('xiao')) #None
print(scores.get('xm',99)) #99是在查找xm不存在时的默认值
key的判断:
-
in 指定的key在字典中存在返回True,‘lisa’in scores
-
not in 指定的key在字典中不存在返回True,‘xm’not in scores
'''key的判断'''
scores={'lisa':100,'kry':200}
print('lisa' in scores) #True
print('kry' not in scores)#False
del scores['lisa'] #删除指定的key-value对
print(scores)#{'kry': 200}
scores.clear() #清空字典的元素
print(scores) #{}
5. 字典元素的增、删、改操作
① 新增元素
scores['money']=99
② 删除元素
del scores['lisa']
scores.clear() 清空字典的元素
③ 修改元素
scores['money']= 100
获取字典视图的三个方法:
- keys()——获取字典的所有key
- values()——获取字典的所有value
- items()——获取字典中所有key,value对
'''获取字典视图的三个方法'''
scores={'lisa':100,'kry':200}
#获取所有的key
keys=scores.keys()
print(keys) #dict_keys(['lisa', 'kry'])
print(type(keys))#<class 'dict_keys'>
print(list(keys)) #将所有key组成的视图转成列表 ['lisa', 'kry']
#获取所有的value
values=scores.values()
print(values) #dict_values([100, 200])
print(type(values)) #<class 'dict_values'>
print(list(values)) #将所有value组成的视图转成列表 [100, 200]
#获取所有键值对key-value
items=scores.items()
print(items) #dict_items([('lisa', 100), ('kry', 200)])
print(list(items)) #转换之后的列表元素是由元组组成 [('lisa', 100), ('kry',200)])
字典元素的遍历:
for item in scores:
print(item)
#字典元素的遍历
scores={'lisa':100,'kry':200,'wang':300}
for item in scores:
print(item,scores[item],scores.get(item))
'''lisa 100 100
kry 200 200
wang 300 300'''
字典的特点:
- 字典中所有元素都是一个key-value对,key不允许重复,value可以
- 字典中的元素是无序的
- 字典中的key必须是不可变对象
- 字典也可以根据需要动态的伸缩
- 字典会浪费较大的内存,是一种用空间换时间(查找速度快)的数据结构
6. 字典生成式
内置函数zip():用于将可迭代对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表
字典生成式:
{item.upper():price for item,price in zip(items,prices)}
items=['fruit','book','others','kry']
prices=[96,23,85]
d={item.upper():price for item,price in zip(items,prices)}#zip以短的进行创建
print(d) #{'FRUIT': 96, 'BOOK': 23, 'OTHERS': 85}
总结:
十三、元组
1. 什么是元组
元组:python内置的数据结构之一,是一个不可变序列
不可变序列和可变序列:
不可变序列(无增、删、改操作):字符串、元组
可变序列(可增、删、改操作,对象地址不发生更改):列表、字典、集合
元组表达式:
t=('python','hello',90)
注意:列表[]、元组()
'''可变序列 :列表,字典'''
lst=[10,2,4]
print(lst,id(lst)) #[10, 2, 4] 2109434818496
lst.append(30)
print(lst,id(lst)) #[10, 2, 4, 30] 2109434818496
dict={'lisa':25,'jenny':24}
print(dict,id(dict))#{'lisa': 25, 'jenny': 24} 2109434769472
dict.clear()
print(dict,id(dict))#{} 2109434769472
'''不可变序列:字符串、元组'''
str='hello'
print(id(str)) #1622997987120
str+='world'
print(id(str)) #1622998041264
2. 元组的创建方式
-
直接使用小括号()
t=('python','hello',90) -
使用内置函数 tuple()
t=tuple( ('python','hello',90) ) -
只包含一个元组的元素需要使用逗号和小括号
t = (10,)
'''元组的创建方式'''
#1、使用()
t=('python','world',98)
#如果元组中只有一个元素,逗号不能省
t=('python',)
print(t) #('python',)
print(type(t))#<class 'tuple'>
#2、使用内置函数tuple()
t1=tuple(('python','world',98))
print(t1,type(t1)) #('python', 'world', 98) <class 'tuple'>
'''空列表'''
lst=[]
lst1=list()
'''空字典'''
d={}
d1=dict()
'''空元组'''
t=()
t1=tuple()
print('空列表',lst,lst1) #空列表 [] []
print('空字典',d,d1) #空字典 {} {}
print('空元组',t,t1) #空元组 () ()
为什么要将元组设计成不可变序列?
- 在多任务环境下,同时操作对象时不需要加锁,因此,在程序中尽量使用不可变序列
注意事项:元组中存储的是对象的引用
- a、如果元组中对象本身不可变对象,则不能再引用其它对象
- b、如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变
t=(10,[20,30],9)
print(t) #(10, [20, 30], 9)
print(type(t)) #<class 'tuple'>
print(t[0],type(t[0]),id(t[0]))#10 <class 'int'> 140728196847552
print(t[1],type(t[1]),id(t[1]))#[20, 30] <class 'list'> 2261544792000
print(t[2],type(t[2]),id(t[2]))#9 <class 'int'> 140728196847520
'''尝试将t[1]修改为100'''
# t[1]=100 元组不允许修改元素
'''由于[20,30]列表,而列表是可变序列,所以可以向列表中添加元素,而列表的内存地址不变'''
t[1].append(100) #向列表中添加元素
print(t) #(10, [20, 30, 100], 9)
3. 元组的遍历
元组是可迭代对象,可使用 for...in...进行遍历
for item in t:
print(item)
'''元组的遍历'''
t=('python','world',90)
'''第一种方式,使用索引'''
print(t[0]) #python
'''第二种方式,for...in'''
for item in t:
print(item,end='\t') #python world 90
十四、集合
1. 什么是集合
- python语言提供的内置数据结构
- 与列表、字典一样都属于可变类型的序列
- 集合是没有value的字典
2. 集合的创建
- 使用{}
- 使用内置函数set()
#集合的创建方式
#第一种使用{}
s={1,2,1,1,3}#集合中的元素不允许重复
print(s,type(s)) #{1, 2, 3}
#第二种方式 内置函数set()
s1=set(range(6))
print(s1) #{0, 1, 2, 3, 4, 5}
#可以将列表类型元素转为集合
s2=set([2,3,45])
print(s2,type(s2))
#可以将元组类型元素转为集合,集合中的元素是无序的
s3=set((2,4,5,33,67))
print(s3,type(s3)) #{33, 2, 67, 4, 5} <class 'set'>
#将字符串类型转为集合
s4=set('python')
print(s4,type(s4))#{'p', 'o', 'n', 'y', 'h', 't'} <class 'set'>
#将字典转为集合
s5=set({1,23,4,5,1})
print(s5,type(s5))#{1, 4, 5, 23} <class 'set'>
#定义一个空集合
s6={} #dict字典类型
print(type(s6))#<class 'dict'>
s7=set()
print(s7,type(s7))#set() <class 'set'>
3. 集合的增、删、改、查操作
① 集合元素的增加
- add(),一次添加一个元素
- update(),至少添加一个元素
② 集合元素的删除
- 调用remove()方法,一次删除一个指定元素,如果不存在出现KeyError
- 调用discard()方法,一次删除一个指定元素,不存在不抛异常
- 调用pop()方法,一次只删除一个任意元素
- 调用clear()方法,清空集合
③ 集合元素的判断
in 或 not in
#集合的相关操作
s={10,20,30,40}
'''集合元素的判断操作'''
print(10 in s) #True
print(10 not in s)#False
'''集合元素的新增操作'''
s.add(80) #一次添加一个元素
print(s)#{40, 10, 80, 20, 30}
s.update({100,200,300}) #至少添加一个元素
print(s) #{100, 40, 200, 10, 300, 80, 20, 30}
s.update([111,222])#添加列表
s.update((19,29,39))#添加元组
print(s)#{100, 39, 40, 200, 10, 300, 111, 80, 29, 19, 20, 222, 30}
'''集合元素的删除操作'''
s.remove(100)
#s.remove(500)KeyError
print(s) #{39, 40, 200, 10, 300, 111, 80, 29, 19, 20, 222, 30}
s.discard(500) #不存在,不抛出异常
s.discard(200)
print(s) #{39, 40, 10, 300, 111, 80, 29, 19, 20, 222, 30}
s.pop() #不能加参数
print(s)#{40, 10, 300, 111, 80, 29, 19, 20, 222, 30}
s.clear()#清空集合
print(s)#set()
4. 集合间的关系
集合间的关系:
- 两个集合是否相等(元素相同,就相等) ==/!=
- 一个集合是否是另一个集合的子集 a.issubset( b )
- 一个集合是否是另一个集合的超集 a.issuperset( b )
- 两个集合是否没有交集 a.isdisjoint( b )
s={10,20,30,40}
s2={40,30,20,10}
'''两个集合是否相等(元素相同,就相等)'''
print(s==s2)#True
print(s!=s2)#False
'''一个集合是否是另一个集合的子集'''
s1={1,2,3,4,5}
s2={1,2,3}
s3={4,5,6}
print(s2.issubset(s1))#True
print(s3.issubset(s1))#False
'''一个集合是否是另一个集合的超集'''
print(s1.issuperset(s2))#True
print(s1.issuperset(s3))#False
'''两个集合是否没有交集'''
print(s2.isdisjoint(s3))#True
print(s2.isdisjoint(s1))#False****
集合的数学操作:
- 交集 &/intersection()
- 并集 |/union()
- 差集 -/difference()
- 对称差集 ^/symmetric_difference()
#集合的数学操作
'''1、交集操作'''
s1={10,20,30,40}
s2={20,30,40,50,60}
print(s1.intersection(s2))#{40, 20, 30}
print(s1 & s2) # & 与intersection()等价,交集操作 {40, 20, 30}
'''2、并集操作'''
print(s1.union(s2)) #{40, 10, 50, 20, 60, 30}
print(s1 | s2) # | 与union()等价,并集操作
print(s1,s2) #s1和s2没有发生变化
'''3、差集操作'''
print(s1.difference(s2)) #10
print(s1-s2) # - 与difference()等价,差集操作
'''4、对称差集'''
print(s1.symmetric_difference(s2))#{50, 10, 60}
print(s1^ s2) # ^ 与symmetric_difference()等价,对称差集
5. 集合生成式
公式:
{i * i for i in range(1,10)}
注意:将{ }修改为[ ]就是列表生成式,没有元组生成式
'''列表生成式'''
lst =[ i*i for i in range(6)]
print(lst) #[0, 1, 4, 9, 16, 25]
'''集合生成式'''(无序)
s={ i*i for i in range(10)}
print(s) #{0, 1, 64, 4, 36, 9, 16, 49, 81, 25}
总结:
十五、字符串
1. 字符串的驻留机制
字符串是基本数据类型,是一个不可变的序列。
什么叫字符串驻留机制?
仅仅保持一份相同且不可变字符串的方法。 不同的值被放在字符串的驻留池中,python的驻留机制对相同字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量。
'''字符串的驻留机制'''
a='python'
b='python'
c='python'
print(a,id(a))#***python 2397019759600***
print(b,id(b))#***python 2397019759600***
print(c,id(c))#***python 2397019759600***
驻留机制的几种情况(交互模式)
- 字符串的长度为0或1时
- 符合标识符的字符串
- 字符串只在编译时进行驻留,而非运行时
- [ -5 , 256 ]之间的整数数字
sys中的intern方法强制2个字符串指向同一个对象(只针对字符串)
字符串驻留机制的优缺点:
- 当需要相同字符串时,可以直接从字符串池中拿来使用,避免频繁的创建和销毁,提升效率和节约内存。因此,拼接字符串是会比较影响性能的
- 在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方法是要先计算所有字符中的长度,然后再拷贝,只new一次对象,效率比+高
2. 字符串的常用操作
s='hello,hello'
print(s.index('lo'))#3
print(s.rindex('lo'))#9
print(s.find('lo'))#3
print(s.rfind('lo'))#9
#print(s.index('k')) valueError
#print(s.rindex('k'))
print(s.find('k'))#-1
print(s.rfind('k'))#-1
s='hello,python'
a=s.upper()
print(a,id(a))#HELLO,PYTHON 2311083114608 转成大写之后,会产生一个新的字符串对象
print(s,id(s))#hello,python 2311082731248
b=s.lower()#转换之后,会产生一个新的字符串对象
print(b,id(b))
print(s,id(s))
print(b==s)
print(b is s)#False
'''大小写互换'''
s2='Hello,python'
print(s2.swapcase())#hELLO,PYTHON
print(s2.capitalize())#Hello,python
print(s2.title())#Hello,Python
s='hello,python'
'''居中对齐'''
print(s.center(20,'*'))#****hello,python****
'''左对齐'''
print(s.ljust(20,'*'))#hello,python********
print(s.ljust(10))#hello,python
'''右对齐'''
print(s.rjust(20,'*'))#********hello,python
print(s.rjust(20))# hello,python
'''右对齐,使用0进行填充'''
print(s.zfill(20))#00000000hello,python
print(s.zfill(10))#hello,python
print('-890'.zfill(8))#-0000890
s='hello world python'
lst=s.split()#返回值是一个列表
print(lst)#['hello', 'world', 'python']
s1='hello|world|python'
'''从字符串左侧劈分'''
print(s1.split(sep='|'))
print(s1.split(sep='|',maxsplit=1))#['hello', 'world|python']
'''从字符串右侧劈分'''
print(s.rsplit())
print(s1.rsplit(sep='|'))
print(s1.rsplit(sep='|',maxsplit=1))#['hello|world', 'python']
s='hello,python'
print('1、',s.isidentifier())#false
print('2.','12_hh'.isidentifier())#false
print('3','hh_12'.isidentifier())#true
print('4.','hello'.isidentifier())#true
print('5.','\t'.isspace())#true
print('6.',' '.isspace())#true
print('7.','abc'.isalpha())#true
print('8.','张三'.isalpha())#true
print('9.','张三1'.isalpha())#false
print('10.','124'.isdecimal())#true
print('11.','123四'.isdecimal())#false
print('12.','ⅠⅡ'.isdecimal())#false
print('13.','123'.isnumeric())#true
print('14.','123四'.isnumeric())#true
print('15.','ⅠⅡ'.isnumeric())#true
print('16.','abc'.isalnum())#true
print('17.','张三123'.isalnum())#true
print('18.','张三'.isalnum())#true
print('19.','abc!'.isalnum())#false
3. 字符串的比较
print('apple'>'app')#true
print('apple'>'banana')#false
print(ord('a'),ord('b'))#97 98
print(ord('甘'))#29976
print(chr(97),chr(98))#a b
print(chr(29976))
'''==与is的区别
==比较的时value
is 比较的是id是否相等'''
a=b='python'
c='python'
print(a==b)#true
print(b==c)#true
print(a is b)#true
print(b is c)#true
4. 字符串的切片操作
字符串是不可变类型
- 不具备增、删、改等操作
- 切片操作将产生新的对象
s='hello,python'
s1=s[:5]#由于没有指定起始位置,从0开始
s2=s[6:]#由于没有指定结束位置,到字符串结尾结束
print(s1)
print(s2)
print(s1+'!'+s2)
print(id(s1))
print(id(s2))
print('----切片[start:end:step]----')
print(s[1:5:1])#从1开始截至到5,不包含5,步长为1 ello
print(s[::2])#hlopto 默认从0开始,没有写结束,默认到字符串的最后一个元素,步长为2,两个元素之间的索引间隔为2
print(s[::-1])#nohtyp,olleh 默认从字符串的最后一个元素开始,到字符串的第一个元素结束,因为步长为负数
print(s[-6::1])#python 从索引为-6开始,到字符串的最后一个元素,步长为1
5. 格式化字符串
#格式化字符串
#1、%占位符
name='甘雨金'
age=23
print('我叫%s,今年%d岁了' % (name,age) )#我叫甘雨金,今年23岁了
#2、{}
print('我叫{0},今年{1}岁,我真的{1}岁了'.format(name,age))#我叫甘雨金,今年23岁,我真的23岁了
#3、f-string
print(f'我叫{name},今年{age}岁')#我叫甘雨金,今年23岁
print('%10d' % 99)# 99 10表示的是宽度
print('%.3f' % 3.1415926)#3.142 .3表示小数点后三位
#同时表示宽度和精度
print('%10.3f' % 3.1415926)# 3.142
print('{0:.3}'.format(3.1415926))#3.14 .3表示的是一共三位
print('{:.3f}'.format(3.1415926))#3.142 .3f表示是3位小数
print('{:10.3f}'.format(3.1415926))# 3.142
6. 字符串的编码转换
s='天涯共此时'
#编码
print(s.encode(encoding='GBK'))#b'\xcc\xec\xd1\xc4\xb9\xb2\xb4\xcb\xca\xb1'在GBK这种编码格式中 一个中文占两个字节
print(s.encode(encoding='UTF-8'))#b'\xe5\xa4\xa9\xe6\xb6\xaf\xe5\x85\xb1\xe6\xad\xa4\xe6\x97\xb6'在UTF-8这种编码格式中,一个中文占三个字节
#解码
#byte代表的就是一个二进制数据(字节类型的数据)
byte=s.encode(encoding='GBK')#编码
print(byte.decode(encoding='GBK'))#天涯共此时 解码
byte=s.encode(encoding='UTF-8')#编码
print(byte.decode(encoding='UTF-8'))#天涯共此时 解码
总结三(十一到十五)
字符串总结:
列表、字典、元组、集合总结:
十六、函数
1. 函数的创建和调用
什么是函数?
- 函数就是执行特定任务以完成特定功能的一段代码
为什么需要函数?
- 复用代码
- 隐藏实现细节
- 提高可维护性
- 提高可读性便于调试
函数的创建:
def 函数名([输入参数]):
函数体
[return xxx]
函数的创建:
def calc(a,b): #a,b为形参
c=a+b
return c
函数的调用:
result=calc(10,20) #10,20为实参,是函数的调用处
print(result)
2. 函数的参数传递
函数调用的参数传递:
- 位置实参:根据形参对应的位置进行实参传递
- 关键字实参:根据形参名称进行实参传递
def calc(a,b):
c=a+b
return c
result=calc(10,20)#位置参数
print(result)
result1=calc(b=11,a=22)#关键字参数
print(result1)
3. 函数的返回值
函数返回多个值时,结果为元组
print(bool(0))#false
print(bool(1))#true
def fun(num):
odd=[]#奇数
even=[]#偶数
for i in num:
if i%2:
odd.append(i)
else:
even.append(i)
return odd,even
print(fun([11,22,33,44,55,66]))#([11, 33, 55], [22, 44, 66])
'''
函数的返回值
1、如果函数没有返回值,【函数执行完毕之后,不需要给调用处提供数据】return可以省略不写
2、函数的返回值,如果是一个,直接返回类型
3、函数的返回值,如果是多个,返回结果为元组
'''
def fun1():
print('hello')
fun1()#hello
def fun2():
return 'hello'
res=fun2()
print(res)#hello
def fun3():
return 'hello','world'
print(fun3())#('hello', 'world')
'''函数在定义时,是否需要返回值,视情况而定'''
4. 函数的参数定义
① 函数定义默认值参数
函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
def fun(a,b=10):
print(a,b)
#函数的调用
fun(100)# 100 10
fun(20,30)#20 30
print('hello',end='\t')
print('world')#hello world
② 个数可变的位置参数
- 定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
- 使用*定义个数可变的位置形参
- 结果为一个元组
def fun(*args): #个数可变的位置参数
print(args)
fun(10)#(10,)
fun(10,20,30)#(10, 20, 30)
③ 个数可变的关键字参数
- 定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
- 使用**定义个数可变的关键字形参
- 结果为一个字典
def fun(*args): #个数可变的位置参数,结果为元组
print(args)
fun(10)#(10,)
fun(10,20,30)#(10, 20, 30)
def fun1(**args):#个数可变的关键字参数,结果为字典
print(args)
fun1(a=10)#{'a': 10}
fun1(a=10,b=20,c=30)#{'a': 10, 'b': 20, 'c': 30}
'''def fun2(*args,*a):
pass
以上代码,程序会报错,可变的位置参数,只能是1个
def fun2(**args,**kwargs)
以上代码,程序会报错,可变的关键字参数,只能是1个
'''
def fun2(*args,**args2):
pass
'''def fun3(**args,*args): #报错
pass
在一个函数的定义过程中,既有个数可变的关键字形参,也有个数可变的位置形参
要求,个数可变的位置形参放在个数可变的关键字形参之前
'''
def fun(a,b,c): #a,b,c在函数的定义处,所以是形参
print('a=',a,end='\t')
print('b=',b,end='\t')
print('c=',c)
#函数的调用
fun(10,20,30)#函数调用时的参数传递,称为位置传参 a= 10 b= 20 c= 30
lst=[11,22,33]
fun(*lst)#在函数调用时,将列表中的每个元素都转换为位置实参传入 a= 11 b= 22 c= 33
fun(a=100,c=300,b=200)#函数的调用,所以时关键字实参 a= 100 b= 200 c= 300
dic={
'a':111,
'b':222,
'c':333
}
fun(**dic)#在函数调用时,将字典中的键值对都转换为关键字实参传入 a= 111 b= 222 c= 333
'''函数定义时的形参的顺序问题'''
def fun1(a,b,*,c,d,**args): #c d 只能采用关键字实参传递
pass
def fun2(*args,**args2):
pass
def fun3(a,b=10,*args,**args2):
pass
5. 变量的作用域
程序代码能访问该变量的区域。
分为:
- 局部变量:在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变成全局变量
- 全局变量:函数体外定义的变量,可作用于函数内外
#局部:
def fun():
global age
age = 20
print(age)
#全局
name = 'lisa'
def fun1():
print(name)
fun1()#lisa
6. 递归函数
① 什么是递归?
- 在函数体内调用了该函数本身
② 递归的组成部分
- 递归的调用与递归终止条件
③ 递归的调用过程
- 递归每调用一次函数,都会在栈内存分配一个栈帧
- 每执行完一次函数,都会释放相应的空间
④ 递归的优缺点
- 缺点:占用内存多,效率低下
- 优点:思路和代码简单
#使用递归来计算阶乘
def fac(n):
if n==1:
return 1
else:
return n*fac(n-1)
print(fac(6)) #720
#斐波拉且数列(后一项等于前两项相加) 1 1 2 3 5 8
def fib(n):
if n==1:
return 1
elif n==2:
return 1
else:
return fib(n-1)+fib(n-2)
print(fib(6)) #8
#输出这个数列前六项的值
for i in range(1,7):
print(fib(i),end='\t')# 1 1 2 3 5 8
7. lambda表达式
常用来声明匿名函数,只可以包含一个表达式,该表达式的计算结果相当于函数的返回值
f = lambda x,y,z : x+y+z
f(1,2,3)#6
L=[(lambda x:x**2),(lambda x:x**3),(lambda x:x**4)]
print(L[0](2),L[1](2),L[2](2))# 4,8,16
'''没有名字的lambda表达式,作为函数参数'''
L=[1,2,3,4,5]
print(list(map((lambda x:x+10),L)))#[11,12,13,14,15]
8. reduce函数、map函数
- reduce(function,iterable...)函数:会对参数序列中元素进行累积
- map(function,iterable...)函数:根据提供的函数对指定序列做映射
from functools import reduce
# reduce函数
def add(x,y):
return x+y
print(reduce(add,[1,2,3,4,5]))#15
print(reduce(lambda x,y:x+y,[1,2,3,4,5]))
#map函数
def square(x):
return x**2
print(list(map(square,[1,2,3,4,5])))#[1,2,3,16,25]
print(list(map(lambda x:x**2,[1,2,3,4,5])))
总结(十六)
十七、bug
1. bug的由来以及分类
① 粗心导致的语法错误 syntaxError
-
漏了末尾的冒号,如if语句,循环语句,else子句等
-
缩进错误,该缩进的没有缩进,不该缩进的缩进
-
把英文符号携程中文符号,如:引号,冒号,括号
-
字符串拼接的时候,把字符串和数字拼在一起
-
没有定义变量,如while的循环条件的变量
-
‘==’比较运算符和‘=’赋值运算符的混用
② 知识点不熟练导致的错误
- 索引越界问题,indexError
- append()方法使用掌握不熟悉(一次只能增加一个元素)
2. 不同异常类型的处理方式
-
bug的常见类型 序号 | 异常类型 | 描述 | | | -- | ----------------- | --------------- | ------------------------------ | | 1 | ZeroDivisionError | 除(取模)零(所有数据类型) | | | 2 | IndexError | 序列中没有此索引(index) | | | 3 | KeyErrror | 映射中没有这个键 | Dic={‘name’:’lisa’}Dic[‘age’] | | 4 | NameError | 未声明/初始化对象(没有属性) | Print(a) | | 5 | SynatxError | 语法错误 | Int a=20 | | 6 | ValueErrror | 传入无效的参数 | A=int(‘hello’)
-
思路不清导致的问题解决方案
1)使用print()函数 2)使用“#”暂时注释部分代码 -
被动掉坑:程序代码逻辑没错,因为用户操作错误或一些“例外情况”导致程序崩溃
解决方案:Python提供了异常处理机制,可以在异常出现时及时捕获,然后‘消化’,让程序继续运行
1)try...except...
try:
xxx(可能出现异常的代码)
except xx(异常类型):
xxx(异常处理代码)
2)多个except结构:捕获异常的顺序按照先子类后父类的顺序,为了避免遗漏可能出现的异常,可以在最后增加BaseException
#输入两个整数
try:
a=int(input('请输入第一个整数'))
b=int(input('请输入第二个整数'))
result=a/b
print('结果为:',result)
except ZeroDivisionError:
print('对不起,除数不允许为0')
except ValueError:
print('只能输入数字')
print('程序结束')
3)try...except...else结构:如果try中没有抛出异常,则执行else块,如果有异常就执行except块
#输入两个整数
try:
a=int(input('请输入第一个整数'))
b=int(input('请输入第二个整数'))
result=a/b
except BaseException as e:
print('出错了',e)
else:
print('结果为:',result)
print('程序结束')
4)try...except...else...finally结构:finally块无论是否发生异常都会被执行,常用来释放try块中申请的资源
#输入两个整数
try:
a=int(input('请输入第一个整数'))
b=int(input('请输入第二个整数'))
result=a/b
except BaseException as e:
print('出错了',e)
else:
print('结果为:',result)
finally:
print('都会被执行')
print('程序结束')
3. 异常处理机制
traceback模块
import traceback
try:
print('-------------')
print(1/0)
except:
traceback.print_exc()
---------------
Traceback (most recent call last):
File "E:/python1/pythonProject/venv/chap11/p3.py", line 5, in <module>
4. PyCharm的调试模式
断点的三种方式:
- 单击工具栏上的按钮
- 右键单击编辑区:点击debug‘模块名’
- 快捷键:shift+F9
总结(十七)
十八、类与对象
1. 两大编程思想
- 面向过程
- 面向对象
2. 类和对象的创建
类:是多个类似事物组成的群体的统称,能帮我们快速理解和判断事物的性质。
数据类型:
- 不同的数据类型属于不同的类 eg: int str
- 使用内置函数查看数据类型 eg: type(100)
对象:
- 100,99都是int类下的对象,类的实例化
python中一切皆对象
创建类的语法:
class student:
pass
类的组成:
- 类属性
- 实例方法
- 静态方法
- 类方法
class Student:#类名由一个或多个单词组成,首字母大写,其余小写
native_pace='四川' #直接写在类里的变量,称为类属性
def __init__(self,name,age):
self.name=name
self.age=age
#实例方法,在类之内定义发称为方法,类之外定义的称为函数
def eat(self):
print('学生在吃饭....')
#静态方法
@staticmethod
def method():
print('我使用了staticmethod进行修饰,所以我是静态方法,只能被定义一次')
#类方法
@classmethod
def cm(cls):
print('因为我使用了classmethod进行修饰,所以我是类方法')
#python中一切皆对象student是对象吗?内存有开空间吗?
print(id(Student))#2174985910752
print(type(Student))#<class 'type'>
print(Student)#<class '__main__.Student'>
对象的创建(类的实例化)
对象的意义:有了实例,就可以调用类中的内容
语法:
实例名 = 类名()
stu = Student()
同一个页面中
#创建Student类的对象
stu1=Student('张三',20)
print(id(stu1)) #2762497407488
print(type(stu1))#<class '__main__.Student'>
print(stu1.name) #张三
print(stu1.age) #20
stu1.eat() #对象名.方法名 学生在吃饭....
Student.eat(stu1)#类名.方法名(类的对象)->实际上是方法定义处的self学生在吃饭....
3. 类对象和类属性
- 类属性:类中方法外的变量称为类属性,被该类的所有对象共享
- 类方法:使用@classmethod修饰的方法,使用类名直接访问
- 静态方法:使用@staticmethod修饰的方法,使用类名直接访问
print('----访问类属性---')
print(stu1.native_pace)
print('----类方法使用方式-----')
Student.cm()
print('----静态方法----')
Student.method()
4. 类方法和静态方法
python是动态语言,在创建对象后,可以动态的绑定属性和方法。
print('----为stu1动态绑定性别属性-----')
stu1.gender='女'
print(stu1.name,stu1.age,stu1.gender)
print('----为stu1动态绑定方法-----')
def show():
print('定义在类之外的,称为函数')
stu1.show=show
stu1.show()
总结(十八)
十九、面向对象
1. 封装
封装:提高程序的安全性
- 将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法,这样,无序关注方法内部的具体实现细节,从而隔离了复杂度。
- 在python中没有专门修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个"_"
class Student:
def __init__(self,name,age):
self.name=name
self.__age=age
def show(self):
print(self.name,self.__age)
stu=Student('lisa',23)
stu.show() #lisa 23
print(stu.name) #lisa
print(dir(stu))
print(stu._Student__age)# 23 在类的外部可以通过_Student__age进行访问
2. 继承
继承:提高代码的复用性
语法格式:
class 子类类名(父类1,父类2....):
pass
如果一个类没有继承任何类,则默认继承object类
python支持多继承
class A():
pass
class B():
pass
class C(A,B):#多继承
pass
定义子类时,必须在其构造函数中调用父类的构造函数
class Person(object):
def __init__(self,name,age): # __init__就是构造函数
self.name=name
self.age=age
def info(self):
print(self.name,self.age)
class Student(Person):
def __init__(self,name,age,stu_num):
super().__init__(name,age)
self.stu_num=stu_num
class Teacher(Person):
def __init__(self,name,age,tea_year):
super().__init__(name,age)
self.tea_year=tea_year
stu=Student('Lisa',20,'1001')
teacher=Teacher('Jnney',23,12)
stu.info() #Lisa 20
teacher.info()#Jnney 23
3. 方法重写
如果子类对继承自父类的某个属性或方法不满意,可以在子类中对其(方法体)进行重写。
子类重写后的方法可以通过super().xxx()调用父类中被重写的方法。
class Person(object):
def __init__(self,name,age):
self.name=name
self.age=age
def info(self):
print(self.name,self.age)
class Student(Person):
def __init__(self,name,age,stu_num):
super().__init__(name,age)
self.stu_num=stu_num
def info(self):
super().info()
print(self.stu_num)
class Teacher(Person):
def __init__(self,name,age,tea_year):
super().__init__(name,age)
self.tea_year=tea_year
def info(self):
super().info()
print(self.tea_year)
stu=Student('Lisa',20,'1001')
teacher=Teacher('Jnney',23,12)
stu.info() #Lisa 20 1001
teacher.info()#Jnney 23 12
****
4. Object类
- object类是所有类的父类,因此所有类都有object类的属性和方法
- 内置函数dir()可以查看指定对象所有属性
- object有一个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()常用于print()方法,帮我们查看对象的信息,所有我们经常会对__str__()进行重写
class Student:
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):
return '姓名:{0},年龄:{1}'.format(self.name,self.age)
stu=Student('lisa',12)
print(dir(stu))
print(stu)#姓名:lisa,年龄:12
5. 多态
多态:提高程序的可扩展性和可维护性
“具有多种形态”,指即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中使用这个方法
class Animal:
def eat(self):
print('动物会吃')
class Dog(Animal):
def eat(self):
print('狗吃骨头')
class Cat(Animal):
def eat(self):
print('猫吃鱼')
class Person():
def eat(self):
print('人吃五谷杂粮')
#定义一个函数
def fun(obj):
obj.eat()
#开始调用函数
fun(Cat())#猫吃鱼
fun(Dog())#狗吃骨头
fun(Animal())#动物会吃
fun(Person())#人吃五谷杂粮
都有eat方法
| 关于多态的区别 | 静态语言 | 动态语言 |
|---|---|---|
| 实现多态的三个必要条件:继承、方法重写、父类引用指向子类对象 | Python是动态语言,不管对象是什么类型,只关心对象的行为 |
6. 特殊方法和特殊属性
| 名称 | 描述 | ||
|---|---|---|---|
| 特殊属性 | __ dict __ | 获得对象或实例对象所绑定的所有属性和方法的字典 | |
| __ class __ | 输出对象所属的类 | ||
| __ base__ | 输出基类 | ||
| __ bases__ | 输出父类元素 | ||
| __ mro__ | 输出类的层次结构 | ||
| __ subclasses__() | 子类的列表 | ||
| 特殊方法 | __ len__() | 通过重写方法,让内置函数len()的参数可以是自定义类型 | |
| __ add__() | 通过重写方法,可使自定义对象具有+功能 | ||
| __ new__( ) | 用于创建对象 | ||
| __ init__( ) | 对创建的对象进行初始化 |
print(dir(object))
class A:
pass
class B:
pass
class C(A,B):
def __init__(self,name):
self.name=name
#创建c类对象
x=C('Jack')#x是c类型的实例对象
print(x.__dict__)#实例对象和方法len(self.name) stu1=Student('LI')的属性字典
print(C.__dict__)#对象是属性和方法的字典
print(x.__class__)#<class '__main__.C'>输出对象所属的类
print(C.__bases__)#(<class '__main__.A'>, <class '__main__.B'>)C类父类型的元素
print(C.__base__)#<class '__main__.A'>离该类最近的类,基类
print(C.__mro__)#(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)类的层次结构
print(A.__subclasses__())#[<class '__main__.C'>]子类的列表
Eg:
class Student:
def __init__(self,name):
self.name=name
def __add__(self, other):
return self.name+other.name
def __len__(self):
return len(self.name)
stu1=Student('LI')
stu2=Student('Jn')
s=stu1+stu2#实现了两个对象的加法运算(在Student类中编写了__add__())
print(s) #LIJn
s1=stu1.__add__(stu2)
print(s1) #LIJn
print('---------')
lst=[11,22,33,44]
print(len(lst)) #4
print(lst.__len__())#4
print(len(stu1)) #2
Eg:
class Person():
def __new__(cls, *args, **kwargs):
print('__new__()被调用执行了,cls的id值为{0}'.format(id(cls)))#8640
obj=super().__new__(cls)
print('创建对象的id值为{0}'.format(id(obj)))#6928
return obj
def __init__(self,name):
print('__init__被调用,sel的id值为{0}'.format(id(self)))#6928
self.name=name
print('object这个类对象的id为:{0}'.format(id(object)))#5968
print('person这个类对象的id为:{0}'.format(id(Person)))#8640
#创建person类的实例对象
p1=Person('lisa')
print('Persond类的实例对象的id为:{0}'.format(id(p1)))#6928
7. 类的浅拷贝和深拷贝
变量的赋值操作:只是形成两个变量,实际上还是指向同一个对象。
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu=cpu
self.disk=disk
#变量的赋值
cpu1=CPU()
cpu2=cpu1
print(cpu1)#<__main__.CPU object at 0x000001F4B1713520>
print(cpu2)#<__main__.CPU object at 0x000001F4B1713520>
浅拷贝:
python拷贝一般都是浅拷贝,拷贝时,使用copy模块的copy函数,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象。
#类的浅拷贝
print("--------")
disk=Disk()
computer=Computer(cpu1,disk)#创建一个计算机类对象
import copy
computer2=copy.copy(computer)
print(computer,computer.cpu,computer.disk)#6190 3520 6730
print(computer2,computer2.cpu,computer2.disk)#E520 3520 6730
深拷贝:
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同。
#深拷贝
computer3=copy.deepcopy(computer)
print(computer,computer.cpu,computer.disk)#6190 3520 6730
print(computer3,computer3.cpu,computer3.disk)#E1C0 EB50 89D0
总结(十九)
二十、模块
1. 什么叫模块
模块(moudule):在python中一个扩展名为.py的文件就是一个模块,一个模块可以包含N多个函数、类和语句。
好处:
- 方便其它程序和脚本的导入并使用
- 避免函数名和变量名冲突
- 提高代码的可维护性和重用性
2. 自定义模块
创建模块:新建一个.py文件,名称尽量不要与python自带的标准模块名称相同。
导入模块:
① import 模块名称 [as 别名]——>导入所有
② from 模块名称 import 函数/变量/类——>导入一部分
import math
print(id(math))#2809308103760
print(type(math))#<class 'module'>
print(math)#<module 'math' (built-in)>
print(math.pi)#3.141592653589793
print(dir(math))
print(math.pow(2,3),type(math.pow(2,3))) #8.0
print(math.ceil(9.001))#10
print(math.floor(9.999))#9
from math import pi
print(pi)#3.141592653589793
print(math.pow(2,3))#8.0
from math import pow
print(pow(2,3))#8.0
#导入自定义模块
import calc
print(calc.add(1,2))
from calc import div
print(div(2,4))
3. 以主程序的形式执行
if __ name__ == '__ main__':
def add(a,b):
return a+b
if __name__=='__main__':
print(add(1,2))#3 只有当点击运行calc2时,才会运行
import calc2
print(calc2.add(20,30))#50
4. python中的包
-
包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下
Python程序——》包——》模块——》函数,语句等
作用:
- 代码规范
- 避免模块名称冲突
包和目录的区别:
包含__init__.py的目录称为包,而目录不包含该文件
包的导入:
import 包名.模块名
python中常用的内置模块:
| 模块名 | 描述 |
|---|---|
| Sys | 与python解释器及其环境操作相关的标准库 |
| Time | 提供与时间相关的各种函数的标准库 |
| Os | 提供了访问操作系统服务功能的标准库 |
| Calendar | 提供与日期相关的各种函数的标准库 |
| Urllib | 用于读取来自网上(服务器)的标准数据库 |
| Json | 用于使用JSON序列化和反序列化对象 |
| Re | 用于在字符串中执行正则表达式匹配和替换 |
| Math | 提供标准算术运算函数的标准库 |
| Decimal | 用于进行精确控制运算精度、有效位数、四舍五入操作的十进制运算 |
| Logging | 提供了灵活的记录事件、错误、警告、调试信息等日志信息的功能 |
mport sys
print(sys.getsizeof(True))#28
print(sys.getsizeof(False))#24
import time
print(time.time())#1627543877.673728
print(time.localtime())#time.struct_time(tm_year=2021, tm_mon=7, tm_mday=29, tm_hour=15, tm_min=31, tm_sec=17, tm_wday=3, tm_yday=210, tm_isdst=0)
import urllib.request #爬虫
print(urllib.request.urlopen('http://www.baidu.com').read())
5. 第三方模块的安装和使用
-
第三方模块的安装:
pip install 模块名 -
第三方模块的使用:
import 模块名
总结(二十)
二十一、文件操作
1. 编码格式介绍
encoding = gbk(默认utf-8)
2. 文件的读写原理
-
文件的读写俗称‘IO操作’
-
文件读写操作流程
Python操作文件——》打开或新建文件——》读、写文件——》关闭资源 -
内置函数open( )创建文件对象,通过IO流将磁盘文件的内容和程序中的对象中的内容进行同步
语法规则:
file = open (filename [,mode,encoding])
其中,mode:打开模式,默认为只读;
encoding:默认文本文件中字符的编写格式为gbk
3. 文件读写操作
file=open('a.txt','r')
print(file.readlines())
file.close()
file=open('b.txt','w')
file.write('helloworld')
file.close()
4. 文件对象常用的方法
file=open('b.txt','a')
file.write('python')
lst=['java','go','c']
file.writelines(lst)
file.close()
File=open(‘a.txt’,‘r’)//a:中国美丽
File.seek(2)#国 美丽,一个汉字两个字节,如果写1就会报错
print(file.tell())#42
file=open('c.txt','a')
file.write('hello')
file.flush()#file.close()后就不能再添加
file.write('world')
file.close()
5. with语句(上下文管理器,会自动关闭文件)
with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭, 以此来达到释放资源的目的。实现了__enter__()和__exit__()这两个方法的对象,称上下文管理器。 (会自动关闭)
with open ('a.txt','r') as file:
print(file.read())
6. os模块和os.path模块用于对目录或文件进行操作
os模块是python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样
#os模块与操作系统相关的一个模块
import os
os.system('notepad.exe')#调用记事本
os.system('calc.exe')#调用计算器
import os
print(os.getcwd())#E:\python1\pythonProject\venv\chap15
print(os.listdir('../chap15'))#['a.txt', 'b.txt', 'c.txt', 'p1.py', 'p10.py', 'p11.py', 'p12.py', 'p2.py', 'p3.py', 'p9.py']
# print(os.mkdir('newdir3'))
# print(os.makedirs('a/b/d'))
# print(os.rmdir('newdir1'))
# print(os.removedirs('a/b/c'))
os.chdir('E:\\python1\\pythonProject\\venv\\chap14')
print(os.getcwd())#E:\python1\pythonProject\venv\chap14
#列出指定目录下的所有py文件
import os
path=os.getcwd()
print(path)#E:\python1\pythonProject\venv\chap15 返回当前工作目录
lst=os.listdir(path)
print(lst)#返回指定目录下的文件
for filename in lst:
if filename.endswith('.py'):
print(filename)
import os.path
print(os.path.abspath('a.txt'))#E:\python1\pythonProject\venv\chap15\a.txt
print(os.path.exists('b.txt'))#True
print(os.path.join('E:\\python1','demo12.py'))#E:\python1\demo12.py
print(os.path.split('E:\python1\demo12.py'))#('E:\\python1', 'demo12.py')
print(os.path.splitext('demo.py'))#('demo', '.py')
print(os.path.basename('E:\python1\demo12.py'))#demo12.py
print(os.path.dirname('E:\python1\demo12.py'))#E:\python1
print(os.path.isdir('demo.py'),os.path.isdir('E:\\python1\\chap15'))#False False:
import os
path=os.getcwd()
lst_files=os.walk(path)#walk可以递归遍历所有的文件,能获取指定目录和指定目录下的子文件,
for dirpath,dirname,filename in lst_files:
# print(dirpath)
# print(dirname)
# print(filename)
# print('------------------')
for dir in dirname:
print(os.path.join(dirpath,dir))
print('---------------')
for file in filename:
print(os.path.join(dirpath,file))