Python
Python中的输出函数
print()函数输出的内容可以是数字、字符串、含有运算符的表达式;
print(520)
print('helloworld')
print(3+1)
#3,1是操作数,'+'是运算符,总的成为表达式,会进行运算输出表达式的结果
print()函数可以将内容输出到文件或者显示器中;
#将数据输出到文件中,1:所指定的盘符要存在;2:使用file=fp
fp=open('D:/text.txt','a+')
#'a+'中'a'是读写的方式打开文件,'+'是追加模式,不会覆盖原本内容
#如果文件不存在就创建,存在就在文件内容的后面继续追加
print('helloworld',file=fp)
fp.close()
#前提是有D盘
#输出到文件当中open close
#不进行换行输出(输出内容在一行当中)
print('hello','world','Python')
print()函数可以输出换行或不换行.
注释:#
转义字符
反斜杠+想要实现转移功能首字母
eg:换行 \n 回车\r 水平制表符\t 退格\b
#转义字符
print('hello\nworld')
print('hello\tworld')
print('helloooo\tworld')
#四个字符为一个单元格,占满就重新开一个
print('hello\rworld') #world把hello覆盖掉了
print('hello\bworld') #退一个格将'hello'中o退没了
print('http:\\www.baidu.com') #只有一个'\'
print('http:\\\www.baidu.com') #有两个'\'
print('老师说:\'大家好\'') #老师说:'大家好'
#原字符:不希望字符中的转义字符起作用,就使用原字符,就是在字符串之前加上r或R
print(r'hello\nworld') #hello\nworld
#注意:最后一个字符不能是反斜杠
#print(r'hello\nworld\')
#但可以是两个
print(r'hello\nworld\\')
七十二变
1、二进制与字符编码
1024byte=1kB
1024KB=1MB
1024MB=1GB
1024GB=1TB
Unicode中英文都为两个字节表示
UTF-8 英1,中3
print(chr(100111001011000)) #太长了
print(chr(0b100111001011000)) #0b表示为二进制,表示乘法的乘
print(ord('乘')) #20056十进制
#一个字符对应一个整数,十进制、八进制、十六进制,最终都转换为二进制被识别
2、Python中的标识符与保留字
保留字:有一些单词被赋予特定的意义,这些单词在给任何对象其名字的时候都不能用。
标识符:变量、函数、类、模块和其他对象的起的名字。
标识符规则:
1>字母、数字、下划线;
2>不能以数字开头;
3>不能是保留字;
4>严格区分大小写
3、Python中的变量与数据类型
变量
name='玛丽亚'
print(name)
print('标识',id(name))
print('类型',type(name))#类型 <class 'str'>
print('值',name) #值 玛丽亚
变量由三部分组成:
标识:表示对象所存储的内存地址,使用内置函数id(obj)来获取
类型:表示对象的数据类型,使用内置函数type(obj)来获取
值:表示对象所存储的具体数据,使用print(obj)可以将值进行打印输出
name='玛丽亚'
print(name)#玛丽亚
name='楚留冰'
print(name)#楚留冰
当多次赋值之后,变量名会指向新的空间
数据类型
常用的数据类型:
int 整数类型
float 浮点数类型
bool 布尔类型
str 字符串类型
1>整数类型:
十进制(默认的进制)
二进制 (0b)
八进制 (0o)
十六进制 (0x)
print('十进制',118)
print('二进制',0b10101111)#二进制 175
print('八进制',0o176)#八进制 126
print('十六进制',0x1EAF)#十六进制 7855
2>浮点类型
整数部分和小数部分组成
浮点数存储不精确性
a=3.14159
print(a,type(a))
n1=1.1
n2=2.2
print(n1+n2)#3.30000000000000000
解决方案:导入模块decimal
from decimal import Decimal
print(Decimal('1.1')+Decimal('2.2')) #3.3
3>布尔类型
True 真 1,False 假 0
python中的布尔值可以转换为整数进行运算
f1=True
f2=False#首字母大写
print(f1,type(f1))
print(f1+1)#2
print(f2+1)#1
4>字符串类型
又称为不可变的字符序列;
可以使用单引号’ ‘,双引号" “,三引号”"" “”"或’’’ ‘’'来定义字符串;
单引号和双引号定义的字符串必须在一行;
三引号定义的字符串可以分布在连续的多行。
str1='人生苦短,我用python'
print(str1,type(str1))
str2="人生苦短,我用python"
print(str2,type(str1))
str3='''人生苦短,
我用python'''#多行显示
print(str3,type(str1))
str4="""人生苦短,
我用python"""#多行显示
print(str4,type(str1))
4>数据类型转换
name='张三'
age=20
print(type(name),type(age)) #说明name与age 的数据类型不相同
print('我叫'+name+'今年'+age+'岁')#'+'是连接符
#当将str类型与int类型进行连接时,报错
#解决方案:类型转换
print('我叫'+name+'今年'+str(age)+'岁')#int通过str函数转换为str类型,不再报错
str() 将其他类型转换为str类型
int() 将其他数据类型转换为整数类型:
str转int 前提:字符串为数字串,还得是整数,字符串不能为小数串,非数字串不允许转换
float转int :只截取整数部分,舍去小数部分
bool转int :True转为1
float():
int,bool 转float:加’.0’
str转float:字符串中的数据如果是非数字串,不允许转换
4、Python中的注释
三种类型:
1>单行注释:以"#"开头,直到换行结束
2>多行注释:并没有单独的多行注释标记,将一对三引号之间的代码成为多行注释
#coding:gbk
#中文编码声明注释
'''我是
多行注释'''
3>中文编码声明注释:在文件开头加上中文声明注释,用以指定源码文件的编码格式
算你赢
1、Python的输入函数input()
作用:接受来自用户的输入
返回值类型:输入值的类型为str
值的存储:对输入的值进行存储
input()函数的基本使用:
present = input(‘提问’)
#present是变量
present=input('大圣想要什么礼物呢?')#定海神针
print(present,type(present))#定海神针 <class 'str'>
#从键盘区录入两个整数,计算两个整数的和
a=input('请输入一个加数:')#10
b=input('请输入另一个加数:')#20
print(a+b)#1020 #连接
print(type(a),type(b))#<class 'str'> <class 'str'>
#解决方案:类型转换
#1111111
a=int(a)#将转换之后的结果存储到a中
b=int(b)
print(a+b)#30
#222222
a=int(input('请输入一个加数:'))
b=int(input('请输入另一个加数:'))
print(a+b)#30
2、Python中的运算符:
算术运算符:
标准算术运算符:加(+)、减(-)、乘(*)、除(/)、整除(//)
取余运算符:%
幂运算符:**
print(1+1)#加法运算
print(1/2)#除法运算 0.5
print(11//2)#整除运算 5
print(11%2)#取余运算 1
print(2**3)#幂运算 8
%{ 取余(一正一负要公式:余数=被除数-除数商)
*//整数(一正一负向下取整)
#一正一负的整除和取余
print(-9//-4)#2
print(9//-4)#-3 #9除以4得-2.2 向下取整得-3
print(-9//4)#-3
print(9%-4)#-3 #9-(-4)*(-3)=-3
print(-9%4)#3 #-9-4*(-3)=3
赋值运算符
执行顺序: 右->左
支持链式赋值:a=b=c=20
支持参数赋值:+=、-=、*=、/=、//=、%=
支持系列解包赋值:a,b,c=20,30,40
a=b=c=20#链式赋值实际上只有一个整数对象,但是却有a,b,c三个引用指向这个对象
print(a,id(a))
print(b,id(b))
print(c,id(c))
#id(a)=id(b)=id(c)
#参数赋值
a=20
a+=30
print(a)#50
a=20
a/=2#26.666666666666666
print(type(a))#float
a//=2#13.0 #float
a%=3
print(a)#1.0
#解包赋值
a,b,c=20,30,40
print(a,b,c)#等号左右的变量数和值的数必须相等,顺序必须对应
#交换两个变量的值
a,b=10,20
print('交换之前',a,b)
#交换
a,b=b,a
print('交换之后',a,b)#20,10
比较运算符
对变量或表达式的结果进行大小、真假等比较,结果是布尔类型
>,<,>=,<=,!=
== 对象value的比较
is,is not 对象id的比较
#比较运算符
a,b=10,20
print('a>b吗?',a>b) #False
print('a<b吗?',a<b) #True
print('a<=b吗?',a<=b)#True
print('a>=b吗?',a>=b)#False
print('a==b吗?',a==b)#False
print('a!=b吗?',a!=b)#True
#== 比较对象的值
#is 比较对象的标识使用
a=10
b=10
print(a==b)#True 说明a与b value相等
print(a is b)#True 说明a与b的id标识相等
#一下代码未学
list1=[11,22,33,44]
list2=[11,22,33,44]
print[list1==list2]#True
print[list1 is list2]#False
print(id(list1))
print(id(list2))
print(a is not b)#False #a和b的id是不相等的
print(list1 is not list2)#True
布尔运算符
对于布尔值之间的运算
and
or
not
in
not in
#布尔运算
a,b=1,2
#and并且
print(a==1 and b==2) #True #True and True -->True
print(a==1 and b<2) #False #True and False --->False
print(a!=1 and b==2) #False #False and True ---->False
print(a!=1 and b!=2) #False #False and False --->False
#or或者
print(a==1 or b==2) #True #True or True -->True
print(a==1 or b<2) #True #True or ---->True
print(a!=1 or b==2) #True #False or True ---->True
print(a!=1 or b!=2) #False #False or False --->False
#not对布尔类型的操作数进行取反
f=True
f2=False
print(not f) #False
#in not in是否在其中
s='helloworld'
print('w' in s)#True
print('k' in s)#False
print('w' not in s)#False
print('k' not in s)#True
位运算符
位与& ---------对应数位都是1,结果数位才是1,否则为0
位或|----------对应数位都是0,结果数位才是0,否则为1
左移位运算符<<---------高位溢出舍弃,低位补0,向左移动一位相当于乘以2,向左移动n位相当于乘以2的n次方
右移位运算符>> -------低位溢出截断,高位补0,向右移动一位相当于除以2,向右移动n位相当于除以2的n次方
print(4<<1)#8向左移动一位
print(4<<2)#16向左移动两位
print(4>>1)#2向右移动一位
print(4>>2)#1向右移动两位
3、运算符的优先级
先算术运算** *,/,//,% +,-
再位运算<< >> & |
再比较运算>,<,>=,<=,==,!= (结果为True False ,结果再进行布尔运算)
再布尔运算and or
最后赋值运算 =
*有括号的要先计算括号里的内容
往哪走
1、程序的组织结构
顺序结构
选择结构 if语句
循环结构 while语句
for-in 语句
2、顺序结构
程序从上到下顺序地执行代码,中间没有任何的判断和跳转,直接到程序结束
3、对象的布尔值
Python一切皆对象,所有对象都有一个布尔值
获取对象的布尔值使用内置函数bool()
*以下对象的布尔值为False
False
数值0
None
空字符串
空列表
空元组
空字典
空集合
除了以上的剩下的其他对象的布尔值均为True
#测试对象的布尔值
#以下均为False
print(bool(False)) #False
print(bool(0))#False
print(bool(0.0))#False
print(bool(None))#False
print(bool(''))#False#空字符串
print(bool(""))#False#空字符串
print(bool([]))#空列表#False
print(bool(list()))#空列表#False
print(bool(()))#空元组#False
print(bool(tuple()))#空元组#False
print(bool({}))#空字典#False
print(bool(dict()))#空字典#False
print(bool(set()))#空集合#False
#除了以上的剩下的其他对象的布尔值均为True
print(bool('helloworld'))#True
4、分支结构:
选择结构:
程序根据判断条件的布尔值选择地执行部分代码,明确的让计算机知道在什么条件下,该去做什么
单分支if结构
if 条件表达式 :
条件执行体
money=1000#余额
s=int(input('请输入取款金额')) #取款金额
#判断余额是否充足
if money>=s:
money=money-s
print('取款成功,余额为:',money)
**双分支if...else结构**
if 条件表达式 :
条件执行体1
else:
条件执行体2
#双分支结构if...else 二选一执行
#从键盘录入一个整数,让计算机判断是奇数还是偶数
num=int(input('请输入一个整数'))
#条件判断
if num%2==0:
print(num,'是偶数')
else:
print(num,'是奇数')
**多分枝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
小于0或大于100为非法数据'''
score=int(input('请输入一个成绩'))
#判断
if score>=90 and score<=100:
print('A')
elif score>=80 and score<=89:
print('B')
elif score>=70 and score<=79:
print('C')
elif score>=60 and score<=69:
print('D')
elif score>=0 and score<=59:
print('E')
else:
print('对不起,成绩有误')
#python独有
if 90<=score<=100:
print('A')
elif 80<=score<=89:
print('B')
elif 70<=score<=79:
print('C')
elif 60<=score<=69:
print('D')
elif 0<=score<=59:
print('E')
else:
print('对不起,成绩有误')
**if语句的嵌套**
if 条件表达式1 :
if 内层条件表达式1 :
内存条件执行体1
else :
内存条件执行体2
else :
条件执行体
'''会员 >=200 八折
>=100 九折
不打折
非会员 >=200 9.5折
不打折'''
answer=input('您是会员吗?y/n')
money=float(input('请输入您的购物金额:'))
#判断
if answer=='y': #是会员
if money>=200:
print('打八折付款金额为:',money*0.8)
elif money>=100:
print('打九折付款金额为:',money*0.9)
else:
print('付款金额为:',money)
else:
if money>=200 :
print('打9.5折付款金额为:',money*0.95)
else:
print('付款金额为:',money)
**条件表达式**
条件表达式是if...else的简写
语法结构:
x if 判断条件 else y
运算规则:
如果判断条件的布尔值为True,条件表达式的返回值为x,否则条件表达式的返回值为False
#要求录入两个整数,比较两个数的大小
num_a=int(input('请输入第一个整数'))
num_b=int(input('请输入第二个整数'))
#比较11111111111111
if num_a>=num_b :
print(num_a,'大于等于',num_b)
else:
print(num_a,'小于',num_b)
#比较222222222222
print('使用条件表达式进行比较')
print( str(num_a)+'大于等于'+str(num_b) if num_a>=num_b else str(num_a)+'小于'+str(num_b) )
5、pass空语句
pass语句什么都不做,只是一个占位符,用在语法上需要语句的地方
什么时候使用:
先搭建语法结构,还没想好代码怎么写的时候
哪些语句一起使用:
if语句的条件执行体
for-in语句的循环体
定义函数时的函数体
#pass语句什么都不做,只是一个占位符
answer=input('请输入您是会员吗?y/n')
#判断是否是会员
if answer=='y':
pass
else:
pass
age=int(input('请输入您的年龄:'))
if age:
print(age)
else:
print('年龄为:',age)
转圈圈
1、range()函数的使用
print(),input()也是内置函数
内置函数:不需要加任何前缀直接使用的函数
内置函数range()
用于生成一个整数序列
创建range对象的三种方式:
range(stop) ----> 创建一个(0,stop)之间的整数序列,步长为1
range(start,stop) ------> 创建一个(start,stop)之间的整数序列,步长为1
range(start,stop,step) ------> 创建一个(start,stop)之间的整数序列,步长为step
#range()的三种创建方式
#一、只有一个参数(小括号中只给了一个数)
r=range(10) #[0,1,2,3,4,5,6,7,8,9],默认从0开始,默认相差1---->步长为1
print(r) #range(0,10)
print(list(r))#用于查看range对象中的整数序列 --list是列表的意思
#二、给了两个参数(小括号中给了两个数)
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)#步长为2
print(list(r))#[1,3,5,7,9]
返回值是一个迭代器对象
range类型的优点:不管range对象表示的整数序列有多长,所有range对象占用的内存空间都是相同的,因为仅仅需要存储start,stop和step,只有当用到range对象时,才会去计算序列中的相关元素,如果不用是不计算的
in与not in 判断整数序列中是否存在(不存在)指定的整数
r=range(1,10,2)#步长为2
print(list(r))#[1,3,5,7,9]
#判断指定的整数在序列中是否存在 in,not in
print(10 in r)#False ,10不在当前的r这个整数序列中
print(9 in r)#True
print(10 not in r)#True
print(9 not in r)#False
print(range(1,20,1)) #[1,...,19]
print(range(1,101,1)) #[1,...,100]
循环结构
分类:while循环 ;for-in循环
2、while循环
while 条件表达式 :
条件执行体(循环体)
a=1
#判断条件表达式
if a<10 :
#执行条件执行体
print(a)
a+=1 #1
while a<10 :
#执行条件执行体
print(a)
a+=1
'''
1
2
3
4
5
6
7
8
9'''
选择结构的if 与循环结构的while的区别:
if是判断一次,条件为True执行一行
while是判断N+1次,条件为True执行N次
while循环的执行流程:
四部循环法:
初始化变量
条件判断
条件执行体(循环体)
改变变量
#计算0到4之间的累加和
'''四部循环法
初始化变量
条件判断
条件执行体(循环体)
改变变量
总结初始化的变量与条件判断的变量与改变的变量为同一个 '''
sum=0 #声明一个sum用于存储累加和
#初始化变量为0
a=0
#条件判断
while a<5:
#条件执行体(循环体)
sum+=a
#改变变量
a+=1
print('和为:',sum)#和为:10
#计算1到100之间的偶数和
sum=0
a=1
while a<=100:
if a%2==0:
sum+=a
a++
print('1到100之间的偶数和:',sum)
#计算1到100之间的奇数和
print(bool(0))##################
sum=0
a=1
while a<=100:
if a%2: #a%2 相当于 a%2!=0
sum+=a #加的是奇数
a++
print('1到100之间的偶数和:',sum)
#计算1到100之间的偶数和
print(bool(0)) ########################
sum=0
a=1
while a<=100:
if not bool(a%2): #相当于 a%2==0
sum+=a
a++
print('1到100之间的偶数和:',sum)
3、for-in循环
for-in循环:
in表达从(字符串、序列等)中依次取值,又称为遍历
for-in遍历的对象必须是可迭代对象
for-in的语法结构:
for 自定义的变量 in 可迭代对象 :
循环体
for item in 'Python': #第一次取出来的是'P',将P赋值给item,将item值输出,.......
print(item)
'''
P
y
t
h
o
n'''
#range()产生一个整数序列,也是一个可迭代对象
for i in range(10): ##可以用来记录执行次数
print(i)
'''
0
1
2
3
4
5
6
7
8
9'''
#如果在循环体中,不需要使用到自定义变量,那么可将自定义变量写为'_'
for _ in range(5):
print('人生苦短,我用PYTHON')
'''
人生苦短,我用PYTHON
人生苦短,我用PYTHON
人生苦短,我用PYTHON
人生苦短,我用PYTHON
人生苦短,我用PYTHON
'''
#使用for循环计算1到100之间的偶数和
sum=0
for item in range(1,101):
if item%2==0:
sum+=item
print('1到100之间的偶数和为:',sum)
#要求输出100到999之间的水仙花数
'''举例:
153=3*3*3+5*5*5+1*1*1
'''
for item in range(100,1000):
ge=item%10 #个位上的数
shi=item//10%10 #十位上的数
bai=item//100 #百位上的数
#print(bai,shi,ge)
#判断
if ge**3+shi**3+bai**3==item:
print(item)
循环体内不需要访问自定义变量,可以将自定义变量替代为下划线
4、break、continue与else语句
break语句:
用于结束循环结构,通常与分支结构if一起使用
非正常结束循环
1>
for … in … :
…
if … :
break
2>
while (条件) :
…
if … :
break
#从键盘录入密码,最多录入三次,如果正确就结束循环
for item in range(3):
pwd=input('请输入密码:')
if pwd=='8888':
print('密码正确')
break
else:
print('密码不正确')
a=0
while a<3:
pwd=input('请输入密码:')
if pwd=='8888':
print('密码正确')
break
else:
print('密码不正确')
a+=1
continue语句:
用于结束当前循环,进入下一次循环,通常与分支结构中的if一起使用
1>
for … in … :
…
if … :
continue
…
2>
while (条件) :
…
if … :
continue
…
#要求输出1到50之间所有5的倍数
'''和5的余数为0的数都是5的倍数
和5的余数不为0的数都不是5的倍数
'''
#11111111111111111
for item in range(1,51):
if item%5==0:
print(item)
#222222222222222222
for item in range(1,51):
if item%5!=0:
continue
print(item)
else语句:
与else语句配合使用的三种情况:
1>
if …:
…
else:
…
(if条件表达式不成立时执行else)
2>
while …:
…
else:
…
3>
for …:
…
else:
…
(2>,3>没有碰到break时执行else,循环的执行次序执行完就会执行else)
for item in range(3):
pwd=input('请输入密码')
if pwd=='8888':
print('密码正确')
break
else:
print('密码不正确')
else:
print('对不起,三次密码均输入错误')
a=0
while a<3:
pwd=input('请输入密码:')
if pwd=='8888':
print('密码正确')
break
else:
print('密码不正确')
'''改变变量'''
a+=1
else:
print('对不起,三次密码均输入错误')
5、嵌套循环
是指循环结构中又嵌套了另外的完整的循环结构,其中内层循环作为外层循环的循环体执行
#打印一个3行4列的矩形
for i in range(1,4):#行数,执行三次,一次一行
for j in range(1,5):
print('*',end='\t')#不换行输出 ‘\t’水平制表符,end=''即末尾添加一个空字符
print()#换行
#打印一个直角三角形
for i in range(1,10):
for j in range(1,i+1):
print('*',end='')
print()#换行
#打印一个九九乘法表
for i in range(1,10):
for j in range(1,i+1):
print(i,'*',j,'=',i*j,end='\t')
print()#换行
二重循环中的break和continue:
二重循环中的break和continue用于控制本层循环
#流程控制语句break与continue在二重循环中的使用
for i in range(5):
for j in range(1,10):
if j%2==0:
break
print(j)
print()#五个1
for i in range(5):
for j in range(1,10):
if j%2==0:
continue
print(j,end='\t')
print()#五行1 3 5 7 9
*while循环用来解决次数不固定的循环:
while True:
…
*
一字排开
列表:
变量可以存储一个元素,而列表是一个”大容器“可以存储N多个元素,程序可以方便地对这些数据进行整体操作。
列表相当于其他语言中的数组,但更具有包容性,可以存储不同类型的对象,可以存储多个不同类型的数据类型
a=10 #变量存储的是一个对象的引用
lst=['hello','world',98]
print(id(lst))
print(type(lst))#<class 'list'>
print(lst)
1、列表的创建与删除
列表的创建:
列表需要使用中括号[],元素之间使用英文的逗号进行分隔
列表的创建方式:
使用中括号
eg: lst=[‘大声’,‘卷字节’]
调用内置函数list()
eg: lst2=list([‘大声’,‘卷字节’])
#创建列表的第一种方式:使用[]
lst=['hello','world',98]
#创建列表的第二种方式:使用内置函数list()
lst2=list(['hello','world',98])
##实际上存储的是对象的一个引用
列表的特点:
列表元素按顺序有序排序
索引映射唯一一个数据(列表当中的元素通过索引进行获取)
列表可以存储重复数据
任意数据类型混存
根据需要动态分配和回收内存(不用担心空间问题)
lst=['hello','world',98,'hello']
print(lst)
#索引 采用正数索引,从前往后
print(lst[0])#hello
#索引 从后往前,从-1开始 到-4
print(lst[-4])#hello
2、列表的查询操作
获取列表中指定元素的索引:
index()
1>如果列表中存在N个相同元素,只返回相同元素中的第一个元素的索引
2>如果查询的元素在列表中不存在,则会抛出ValueError
3>还可以在指定的start和stop之间进行查找
lst=['hello','world',98,'hello']
print(lst.index('hello'))#0 #如果列表中存在N个相同元素,只返回相同元素中的第一个元素的索引
print(lst.index('Python'))#ValueError: 'Python' is not in list
print(lst.index('hello',1,3))#ValueError: 'hello' is not in list
print(lst.index('hello',1,4))#3
获取列表中的单个元素:
正向索引从0到N-1 eg:lst[0]
逆向索引从-N到-1 eg:lst[-N]
指定索引不存在,抛出IndexError
lst=['hello','world',98,'hello','world',234]
#获取索引为2的元素
print(lst[2])#98
#获取索引为-3的元素
print(lst[-3])#hello
#获取索引为10的元素
print(lst[10])#IndexError: list index out of range
获取列表中的多个元素:
语法格式:
列表名[start : stop : step ]
切片操作:
-
切片的结果---->原列表片段的拷贝
-
切片的范围----->[start,stop]
-
step默认为1------>简写为[start,stop]
-
step为正数 1> -------> [:stop:step]---->切片的第一个元素默认是列表的第一个元素
2> ------->[start::strp]----->切片的最后一个元素默认是列表的最后一个元素
1>,2>均从start开始往后计算切片 -
step为负数 1> -------> [:stop:step]---->切片的第一个元素默认是列表的最后一个元素
2> ------->[start::strp]----->切片的最后一个元素默认是列表的第一个元素
1>,2>均从start开始往前计算切片
lst=[10,20,30,40,50,60,70,80]
#start=1,stop=6
print(lst[1:6:1])#[20,30,40,50,60]
print('原列表',id(lst))
lst2=lst[1:6:1]
print('切的片段',id(lst2))#新的id
print(lst[1:6])#默认步长为1
print(lst[1:6:])#默认步长为1
#start=1,stop=6,step=2
print(lst[1:6:2])#步长为2 #[20,40,60]
#start默认,stop=6,step=2
print(lst[:6:2])#默认索引从0开始 #[10,30,50]
#start=1,stop默认,step=2
print(lst[1::2])##[20,40,60,80]
######step为负数的情况
print(lst[::-1]) #start,stop默认,step=-1 ###[80,70,60,50,40,30,20,10]
#start=7,stop省略,step=-1
print(lst[7::-1]) ###[80,70,60,50,40,30,20,10]
#start=6,stop=0,step=-2
print(lst[6:0:-2]) ###[70,50,30]
判断指定元素在列表中是否存在:
元素 in 列表名
元素 not in 列表名
print('p' in 'python')#True
print('k' not in 'python')#True
lst=[10,20,'python','hello']
print(10 in lst)#True
print(100 in lst)#False
print(10 not in lst)#False
print(100 not in lst)#True
#######遍历
for item in lst:
print(item)
列表元素的遍历:
for 迭代变量 in 列表名 :
操作
3、列表元素的增、删、改操作
列表元素的增加操作:
方法 | 操作描述 |
---|---|
append() | 在列表的末尾增加一个元素 |
extend() | 在列表的末尾至少添加一个元素 |
insert() | 在列表的任意位置添加一个元素 |
切片 | 在列表的任意位置添加至少一个元素 |
#在列表的末尾增加一个元素
lst=[10,20,30]
print('添加元素之前',lst,id(lst))##[10,20,30] 2181409792960
lst.append(100)
print('添加元素之后',lst,id(lst))##[10,20,30,100] 2181409792960 ###没有生成新的列表对象,只是在原来列表对象后面加了一个元素
lst2=['hello','world']
lst.append(lst2)
print(lst)#[10,20,30,100,['hello','world']] ##lst2作为一个元素添加到lst的末尾
lst.extend(lst2)
print(lst)#[10,20,30,100,'hello','world'] ##向列表的末尾一次性添加多个元素
###在任意位置上添加一个元素
lst.insert(1,90)##在1的位置上添加90
print(lst)#[10,90,20,30,100,'hello','world']
lst3=[True,False,'hello']
#在任意的位置上添加n多个元素
lst[1:]=lst3
print(lst)#[10,True,False,'hello'] #从1开始切切掉即90~'world'被切掉了,然后把lst3放到这个位子上
列表元素的删除操作:
方法 | 操作描述 |
---|---|
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]
lst.remove(100)#ValueError: list.remove(x): x not in list
#pop根据索引移除元素
lst.pop(1)
print(lst)#[10,40,50,60,30]
lst.pop(5)#如果指定位置的索引不存在,将超出异常
print(lst)#IndexError: pop index out of range
lst.pop()#如果不指定参数(索引),删除列表中最后一个元素
print(lst)#[10,40,50,60]
#####切片操作,删除至少一个元素,将产生一个新的列表对象
new_lst=lst[1,3]
print('原列表',lst)#[10,40,50,60]
print('切片后的列表',new_lst)#切片后的列表 [40,50]
#如何不产生一个新的列表对象,而是删除原列表中的内容
lst[1,3]=[]#用空列表去替代当前位置的内容
print(lst)#[10,60]
#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]=[300,400,500,600]
print(lst)#[10,300,400,500,600,40]
4、列表元素的排序
列表元素的排序操作:
常见的两种方式:
-
调用sort()方法,列表中的所有元素默认按照从小到大的顺序进行排序,可以指定 reverse = True,进行降序排列
-
调用内置函数sorted(),可以指定reverse = True,进行降序排列原列表不发生改变
lst=[20,40,10,98,54]
print('排序前的列表',lst,id(lst))
#开始排序,调用列表对象的sort方法,默认是升序排序
lst.sort()
print('排序后的列表',lst,id(lst))#在原列表基础上进行 ##排序后的列表 [10,20,40,54,98]
#通过指定关键字参数,将列表中的元素进行降序排序
lst.sort(reverse=True)#reverse=True表示降序排序
print(lst)#[98,54,40,20,10]
lst.sort(reverse=False)#reverse=False表示升序排序
print(lst)#[10,20,40,54,98]
####使用内置函数sorted()对列表进行排序,将产生一个新列表
lst=[20,40,10,98,54]
print('原列表',lst)#[20,40,10,98,54]
#开始排序
new_lst=lst.sorted()
print(lst)#[20,40,10,98,54]
print(new_lst)#[10,20,40,54,98]
#指定关键字参数,实现列表元素的降序排序
desc_lst=sorted(lst,reverse=True)
print(desc_lst)#[98,54,40,20,10]
5、列表推导式
列表生成式:
简称”生成列表的公式“
语法格式:
[i*i for i in range(1,10)]
注意事项:
“表示列表元素的表达式”中通常包含自定义变量
lst=[i for i in range(1,10)]
print(lst)#[1,2,3,4,5,6,7,8,9]
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内置的数据结构之一,与列表一样是一个可变序列(可以进行增删改操作的序列叫做可变序列)
以键值对的方式存储数据,字典是一个无序的序列(列表是一个有序序列 )
scores={ ‘张三’: 100, ‘李四’: 98, ‘王五’: 45}
字典名 = {键: 值 , 键 : 值 , 键 : 值 }
字典示意图:
放在字典中的键(key)必须是一个不可变序列
整数序列、字符串是不可变序列(不可变序列:不可以进行增删改操作)
列表、字典是可变序列
2、字典的原理
字典的实现原理:
字典的实现原理与查字典类似,Python中的字典是根据key查找value所在的位置
3、字典的创建与删除
字典的创建:
-
最常用的方式:使用花括号:
scores={ ‘张三’: 100, ‘李四’: 98, ‘王五’: 45}
-
使用内置函数dict()
dict(name=‘jack’ , age=20)
#字典的创建方式
'''使用花括号{}创建字典'''
scores={ '张三': 100, '李四': 98, '王五': 45}
print(scores)
print(type(scores))#<class 'dict'>
'''第二种使用内置函数dict()'''
student=dict(name='jack' , age=20)
print(student)
#空字典
d={}
print(d)
4、字典的查询操作
字典的常用操作:
字典中元素的获取:
1> []------>eg: scores[‘张三’]
2> get()方法 ------>eg: scores.get(‘张三’)
#获取字典中的元素
scores={ '张三': 100, '李四': 98, '王五': 45}
'''一、使用[键]'''
print(scores['张三'])#100
print(scores['陈六'])#KeyError: '陈六'
'''二、get(键)'''
print(scores.get('张三'))#100
print(scores.get('陈六'))#None
print(scores.get('麻七',99))#99 实在查找'麻七'所对应的value不存在时所提供的一个默认值
[]取值与使用get()取值的区别:
- []如果字典中不存在指定的key,抛出KeyError异常
- get()方法取值,如果字典中不存在指定的key,并不会抛出KeyError而是返回None,可以通过参数设置默认的value,以便指定的key不存在时返回
key的判断:
in---->指定的key在字典中存在返回True
not in------>指定的key在字典中不存在返回True
#键的判断
scores={ '张三': 100, '李四': 98, '王五': 45}
print('张三' in scores)#True
print('张三' not in scores)#False
5、字典元素的增、删、改操作
字典元素的删除:
del scores[‘张三’]
字典元素的新增:
scores[‘Jack’]=90
scores={ '张三': 100, '李四': 98, '王五': 45}
del scores['张三']#删除指定的key-value对
print(scores)#{'李四': 98, '王五': 45}
#scores.clear()#清空字典的元素
#print(scores)#{}
scores['陈六']=98#新增元素
print(scores)#{'李四': 98, '王五': 45, '陈六': 98}
scores['陈六']=100#修改元素
print(scores)#{'李四': 98, '王五': 45, '陈六': 100}
获取字典视图的三个方法:
keys()------->获取字典中所有key
values()------->获取字典中所有value
items()--------->获取字典中所有key,value对
scores={ '张三': 100, '李四': 98, '王五': 45}
#获取字典中所有key
keys=scores.keys()
print(keys)
print(type(keys))#<class 'dict_keys'>
print(list(keys))#将所有的键组成的视图转换成了列表['张三','李四','王五']
#获取字典中所有values
values=scores.values()
print(values)
print(type(values))#<class 'dict_values'>
print(list(values))#[100,98,45]
#获取字典中所有key,value对
items=scores.items()
print(items)
print(type(items))#<class 'dict_items'>
print(list(items))#[('张三',100),('李四',98),('王五',45)] ###转换之后的列表元素是由元组组成的
字典元素的遍历:
for item in scores :
print(item)
scores={ '张三': 100, '李四': 98, '王五': 45}
#字典元素的遍历,遍历中的键在字典当中都是存在的
for item in scores :
print(item)'''张三
李四
王五'''
for item in scores :
print(item,scores[item],scores.get(item))
'''张三 100 100
李四 98 98
王五 45 45'''
字典的特点:
字典中的所有元素都是一个 key-value对,key不允许重复,value可以重复
字典中的元素是无序的(字典中的位置是计算得出来的,不是人为指定的)
字典中的key必须是不可变对象
字典也可以根据需要动态的伸缩
字典会浪费较大的内存,是一种使用空间换时间的数据结构
d={'name':'张三','name':'李四'}#key不允许重复
print(d)#{'name':'李四'}
d={'name':'张三','nikename':'张三'}#value允许重复
print(d)#{'name':'张三','nikename':'张三'}
lst=[10,20,30]
lst.insert(1,100)
print(lst)#[10,100,20,30]
d={lst:100}
print(d)#TypeError: unhashable type: 'list'
6、字典推导式
字典生成式:
items=[‘Fruits’,‘Books’,‘Others’]
prices=[96,78,85]
{‘FRUITS’:96,‘BOOKS’:78,‘OTHERS’:85}
内置函数zip()
用于将可迭代的对象作为参数,将对象中对应的元素打包成一个元组,然后返回由这些元组组成的列表
items=[‘Fruits’,‘Books’,‘Others’]
prices=[96,78,85]
lst=zip(items,prices)
print(list(lst))
字典生成式:
{item.upper() : price for item,price in zip(items,prices)}
items=['Fruits','Books','Others']
prices=[96,78,85]
d={item:price for item,price in zip(items,prices)}
print(d)#{'Fruits':96,'Books':78,'Others':85}
d={item.upper():price for item,price in zip(items,prices)}
print(d)#{'FRUITS':96,'BOOKS':78,'OTHERS':85} ##item.upper()使其大写
items=['Fruits','Books','Others']
prices=[96,78,85,100,100]
d={item.upper():price for item,price in zip(items,prices)}
print(d)#{'FRUITS':96,'BOOKS':78,'OTHERS':85}
###以元素少的那个为基准进行匹配生成
是排还是散
1、什么是元组
元组:
Python内置的数据结构之一,是一个不可变序列
不可变序列与可变序列:
不可变序列:字符串、元组
不可变序列:没有增、删、改的操作
可变序列:列表、字典
可变序列:可以对序列执行增、删、改操作,对象地址不发生更改
t=( ‘Python’, ‘hello’, 90)
#可变序列:列表、字典
lst=[10,20,45]
print(id(lst))
lst.append(300)
print(id(lst))#地址不变
#不可变序列:字符串、元组
s='hello'
print(id(s))
s=s+'world'
print(id(s))#地址发生改变
print(s)#helloworld
2、元组的创建方式
元组的创建方式:
直接小括号
t=(‘Python’,‘hello’,90)
使用内置函数tuple()
t=tuple((‘Python’, ‘hello’, 90))
只包含一个元组的元素需要使用逗号和小括号
t=(10, )
#元组的创建方式
'''一、直接小括号'''
t=('Python','hello',98)
print(t)
print(type(t))#<class 'tuple'>
t2='Python','hello',98#可以省略了小括号
print(t2)
print(type(t2))#<class 'tuple'>
###t3=('Python')
####print(t3)
###print(type(t3))#<class 'str'>####是str型
t3=('Python',)#如果元组中只有一个元素,逗号不能省,否则为其内容所指本身类型
####print(t3)
###print(type(t3))#<class 'tuple'>
'''二、使用内置函数tuple()'''
t1=tuple(('Python', 'hello', 98))
print(t1)
print(type(t1))#<class 'tuple'>
'''空列表的创建方式'''
lst=[]
lst1=list()
'''空字典的创建方式'''
d={}
d2=dict()
'''空元组的创建方式'''
t4=()
t5=tuple()
print('空列表',lst,lst1)
print('空字典',d,d2)
print('空元组',t4,t5)
为什么要将元组设计成不可变序列
在多任务环境下,同时操作对象不需要加锁
因此,在程序中尽量使用不可变序列
注意事项:
元组中存储的是对象的引用
a)如果元组中对象本身是不可变对象,则不能再引用其他对象
b)如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变
t=(10,[20,30],9)
print(t)
print(type(t))
print(t[0],type(t[0]),id(t[0]))#<class 'int'>
print(t[1],type(t[1]),id(t[0]))#<class 'list'>
print(t[2],type(t[2]),id(t[0]))#<class 'int'>
'''尝试将t[1]修改为100'''
print(id(100))
####t[1]=100#报错,元组不允许修改元素
'''由于[20,30]组成的是列表,列表是可变序列,所以可以向列表中添加元素,而列表的内存地址不变'''
t[1].append(100)#向列表中添加元素
print(t,id(t[1]))##id不发生改变#(10,[20,30,100],9)
3、元组的遍历
元组是可迭代对象,所以可以使用for…in进行遍历
#元组的遍历
t=tuple(('Python','hello',90))
'''一、使用索引'''
print(t[0])
print(t[1])
print(t[2])
'''二、当你不知道有多少元素时,使用for..in进行遍历'''
for item in t:
print(item)
4、什么是集合
集合:
Python语言提供的内置数据结构
与列表、字典一样都属于可变类型的序列
集合是没有value的字典
5、集合的创建
集合的创建方式:
直接{}
s={‘Python’,‘hello’,90}
使用内置函数set()
s=set(range(6))
print(s)
print(set([3,4,53,56]))
print(set((3,4,43,435)))
print(set(‘Python’))
print(set({124,3,4,4,5}))
print(set())
#集合的创建方式
'''一、使用{}'''
s={2,3,4,5,5,6,7,7}#集合中的元素不允许重复
print(s)#{2,3,4,5,6,7}
'''二、使用内置函数set()'''
s1=set(range(6))#转换成集合
print(s1,type(s1))#<class 'set'>
s2=set([1,2,4,5,5,5,6,6])#将列表中的元素转换成集合中的元素类型,同时去掉了重复元素
print(s2,type(s2))#<class 'set'>
s3=set((1,2,4,4,5,65))
print(s3,type(s3))#<class 'set'> #集合中的元素是无序的
#{65,1,2,4,5}
s4=set('python')
print(s4,type(s4))#['n','h','p','y','t','o'] <class 'set'>
s5=set({12,4,34,55,66,44,4})
print(s4,type(s4))#[34,66,4,55,12,44] <class 'set'>
s6={}##dict字典类型
print(type(s6))#<class 'dict'>
#定义一个空集合
s7=set()
print(type(s7))#<class 'set'>
6、集合的增、删、改、查操作
集合元素的判断操作:
in或not in
集合元素的新增操作:
调用add()方法,一次添中一个元素
调用update()方法至少添中一个元素
集合元素的删除操作:
调用remove()方法,一次删除一个指定元素,如果指定的元素不存在抛出KeyError
调用discar()方法,一次删除一个指定元素,如果指定的元素不存在不抛出异常
调用clear()方法,清空集合
s={10,20,30,405,60}
#集合元素的判断操作:
print(10 in s)#True
print(100 in s)#False
print(10 not in s)#False
print(100 not in s)#True
#集合元素的新增操作:
s.add(80)#一次添加一个元素
print(s)#{10,80,20,405,60,30}
s.update({200,400,300})#一次至少添加一个元素
print(s)#{200,10,300,80,400,20,405,60,30}
s.update([100,99,8])#列表
s.update((78,64,56))#元组
print(s)#{64,99,100,200,8,10,300,78,80,400,20,405,56,60,30}
#集合元素的删除操作:
s.remove(100)
print(s)#{64,99,200,8,10,300,78,80,400,20,405,56,60,30}
s.remove(500)
print(s)#KeyError: 500 抛异常
s.discard(500)
print(s)#{64,99,200,8,10,300,78,80,400,20,405,56,60,30}
s.pop()
print(s)#{99,200,8,10,300,78,80,400,20,405,56,60,30} #不一定删除谁
s.pop(400)#pop不能添加参数
print(s)#TypeError: pop() takes no arguments (1 given)
s.clear()#清空
print(s)
集合间的关系:
-
两个集合是否相等:
可以使用运算符==或!=进行判断
-
一个集合是否是另一个集合的子集:
可以调用方法issubset进行判断
B是A的子集 -
一个集合是否是另一个集合的超集:
可以调用方法issupset进行判断
A是B的超集 -
两个集合是否没有交集:
可以调用方法isdisjoint进行判断
# 两个集合是否相等:元素相同就相等
s={10,20,30,40}
s2={30,40,20,10}
print(s==s2)#True
print(s!=s2)#False #集合当中的元素是无序的
#一个集合是否是另一个集合的子集:
s1={10,20,30,40,50,60}
s2={10,20,30,40}
s3={10,20,90}
print(s2.issubset(s1))#True
print(s3.issubset(s1))#False
#一个集合是否是另一个集合的超集:
print(s1.issupset(s2))#True
print(s1.issupset(s3))#False
# 两个集合是否没有交集:
print(s2.isdisjoint(s3))#False#有交集
s4={100,200,300}
print(s2.isdisjoint(s4))#True#没有交集
集合的数学操作:
交集
并集
差集
对称差集
#交集操作
s1={10,20,30,40}
s2={20,30,40,50,60}
print(s1.intersection(s2))
print(s1 & s2) #&和intersection()等价,都是交集操作
print(s1)#没有发生变化{10,20,30,40}
print(s2)#没有发生变化{20,30,40,50,60}
#并集操作
print(s1.union(s2))
print(s1 | s2)#union与| 等价,并集操作
print(s1)#没有发生变化{10,20,30,40}
print(s2)#没有发生变化{20,30,40,50,60}
#差集操作
print(s1.difference(s2))#{10}
print(s1 - s2)
print(s1)#没有发生变化{10,20,30,40}
print(s2)#没有发生变化{20,30,40,50,60}
#对称差集操作
print(s1.symmetric_difference(s2))#{50,10,60}
print(s1 ^ s2)
7、集合生成式
用于生成集合的公式:
{i*i for i in range(1,10) }
将{}修改为[]就是列表生成式
没有元组生成式(不可变序列)
lst=[i*i for i in range(10)]
print(lst)#[0,1,4,9,16,25,36,49,64,81]
s={i*i for i in range(10)}
print(s)#{0,1,64,4,36,9,16,49,81,25}
总结:
一串连一串
1、字符串的驻留机制
字符串:
在Python中字符串是基本数据类型,是一个不可变的字符序列
字符串驻留机制:
仅保存一份相同且不可变字符串的方法,不同的值被存放在字符串的驻留池中,Python的驻留机制对相同的字符串只保留一份拷贝,后续创建相同字符串时,不会开辟新空间,而是把该字符串的地址赋给新创建的变量
可以使用单引号、双引号、三引号来定义
a=‘Python’
b=“Python”
c=’’‘Python’’’
#字符串的驻留机制
a='Python'
b="Python"
c='''Python'''
print(a,id(a))
print(b,id(b))
print(c,id(c))#3个内存地址相同,a,b,c实际上指向内存当中同一块空间
驻留机制的几种情况(交互模式)
字符串的长度为0或1时
符合标识符的字符串
字符串只在编译时进行驻留,而非运行时
[-5,256]之间的整数数字
cmd中
a='abc'
b='ab'+'c'
c=''.join(['ab','c'])
a is b#True
#b的值在运行之前就已经连接完毕了
a is c #False
#c是在程序运行的时候通过join方法将列表当中的数据进行连接的
c#'abc'
type(c)#<class 'str'>
a#'abc'
type(a)#<class 'str'>
a=-5
b=-5
a is b#True
a=-6
b=-6
a is b#False
#强制驻留
import sys
a='abc%'
b='abc%'
a is b#False
a=sys.intern(b)
a is b#True
sys中的intern方法强制2个字符串指向同一个对象
PyCharm对字符串进行了优化处理
字符串驻留机制的优缺点:
当需要值相同的字符串时,可以直接从字符串池里拿来使用,避免频繁的创建和销毁,提升效率和节约内存,因此拼接字符串和修改字符串是会比较影响性能的。
在需要进行字符串拼接时建议使用str类型的join方法,而非+,因为join()方法是先计算出所有字符串中的长度,然后再拷贝,只new一次对象,效率要比“+”效率高。
2、字符串的常用操作
字符串查询操作的方法:
方法名称 | 作用 |
---|---|
index() | 查找子串substr第一次出现的位置,如果查找的子串不存在时,则抛出ValueError |
rindex() | 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则抛出ValueError |
find() | 查找子串substr第一次出现的位置,如果查找的子串不存在时,则返回-1 |
rfind() | 查找子串substr最后一次出现的位置,如果查找的子串不存在时,则返回-1 |
#字符串的查询操作
s='hello,hello'
print(s.index('lo')) #3
print(s.find('lo')) #3
print(s.rindex('lo')) #9
print(s.rfind('lo')) #9
print(s.index('k')) #ValueError: substring not found
print(s.find('k')) #-1
print(s.rindex('k')) #ValueError: substring not found
print(s.rfind('k')) #-1
字符串的大小写转换操作的方法:
方法名称 | 作用 |
---|---|
upper() | 把字符串中所有字符都转成大写字母 |
lower() | 把字符串中所有字符都转成小写字母 |
swapcase() | 把字符串中所有大写字母转换成小写字母,把所有小写字母都转换成大写字母 |
capitalize() | 把第一个字符转换为大写,把其余字符转换为小写 |
title() | 把每个单词的第一个字符转换为大写,把每个单词的剩余字符转换为小写 |
#字符串中的大小写转换的方法
s='hello,python'
a=s.upper()#转换成大写之后,会产生一个新的字符串对象
print(a,id(a))#HELLO,PYTHON
print(s,id(s))#hello,python
b=s.lower()#转换之后,会产生一个新的字符串对象
print(s.lower(),id(b))
print(s,id(s))
print(b==s)#True
print(b is s)#False
s2='hello,Python'
print(s2.swapcase())#HELLO,pYTHON
print(s2.title())#Hello,Python
字符串内容对齐操作的方法:
方法名称 | 作用 |
---|---|
center() | 居中对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度,则返回原字符串 |
ljust() | 左对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串 |
rjust() | 右对齐,第1个参数指定宽度,第2个参数指定填充符,第2个参数是可选的,默认是空格,如果设置宽度小于实际宽度则返回原字符串 |
zfill() | 右对齐,左边用0填充,该方法只接收一个参数,用于指定字符串的宽度,如果指定的宽度小于等于字符串的长度,返回字符串本身 |
s='hello,python'
#居中对齐
print(s.center(20,'*'))#****hello,python****
#左对齐
print(s.ljust(20,'*'))#hello,python********
print(s.ljust(10,'*'))#hello,python
print(s.ljust(20))#hello,python ##
#右对齐
print(s.rjust(20,'*'))#********hello,python
print(s.rjust(10,'*'))#hello,python
print(s.rjust(20))# hello,python##
#右对齐,使用0进行填充
print(s.zfill(20))#00000000hello,python
print(s.zfill(10))#hello,python
print('-8910'.zfill(8))#-0008910###加上减号一共是8位
字符串劈分操作的方法:
方法名称 | 作用 |
---|---|
split() | 从字符串的左边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表 |
以通过参数sep指定劈分字符串是的劈分符 | |
通过参数maxsplit指定劈分字符串时的劈分次数,在经过最大次劈分之后剩余的子串会单独作为一部分 | |
rsplit() | 从字符串的右边开始劈分,默认的劈分字符是空格字符串,返回的值都是一个列表 |
以通过参数sep指定劈分字符串是的劈分符 | |
通过参数maxsplit指定劈分字符串时的最大劈分次数,在经过最大次劈分之后,剩余的字符串会单独作为一部分 |
s='hello world Python'
lst=s.split()
print(lst)#['hello','world','Python']
s1='hello|world|Python'
print(s1.split())#['hello|world|Python']
print(s1.split(sep='|'))#['hello','world','Python']
print(s1.split(sep='|',maxsplit=1))#['hello','world|Python']
##rsplit()从右侧开始劈分
print(s.rsplit())#['hello','world','Python']
print(s1.rsplit('|'))#['hello','world','Python']
print(s1.rsplit(sep='|',maxsplit=1))#['hello|world','Python']
判断字符串操作的方法:
方法名称 | 作用 |
---|---|
isidentifier() | 判断指定的字符串是不是合法的标识符 |
isspace() | 判断指定的字符串是否全部由空白字符组成(回车、换行、水平制表符) |
isalpha() | 判断指定的字符串是否全部由字母组成 |
isdecimal() | 判断指定的字符串是否全部由十进制的数字组成 |
isnumeric() | 判断指定的字符串是否全部由数字组成 |
isalnum() | 判断指定的字符串是否全部由字母和数字组成 |
s='hello,python'
print('1',s.isidentifier())#False
print('2','hello'.isidentifier())#True
print('3','张三_'.isidentifier())#True
print('4','张三_123'.isidentifier())#True
print('5','\t'.isspace())#True
print('6','abc'.isalpha())#True
print('7','张三'.isalpha())#True
print('8','张三1'.isalpha())#False
print('9','123'.isdecimal())#True
print('10','123四'.isdecimal())#False
#罗马数字不是十进制数字 为False
print('11','123'.isnumeric())#True
print('12','123四'.isnumeric())#True
#罗马数字也是数字 也为True
print('13','abc3'.isalnum())#True
print('14','张三123'.isalnum())#True
print('15','abc!'.isalnum())#False
字符串操作的其他方法:
字符串替换:
方法名称 | 作用 |
---|---|
replace() | 第1个参数指定被替换的子串,第2个参数指定替换字串的字符串,该方法返回替换后得到的字符串,替换前的字符串不发生变化,调用该方法时可以通过第3个参数指定最大替换次数 |
字符串的合并:
方法名称 | 作用 |
---|---|
join() | 将列表或元组中的字符串合并成一个字符串 |
s='hello,Python'
print(s.replace('Python','Java'))#hello,Java
s1='hello,Python,,Python,Python'
print(s.replace('Python','Java',2))#hello,Java,Java,Python ##第3个参数指最大的替换次数
lst=['hello','Java','Python']
print('|'.join(lst))#hello|Java|Python
print(''.join(lst))#helloJavaPython
t=('hello','Java','Python')
print(''.join(t))#helloJavaPython
print('*'.join('Python'))#P*y*t*h*o*n##作为字符串序列去进行这样的一个连接
3、字符串的比较
字符串的比较操作:
运算符: >,>=,<,<=,==,!=
比较规则:
首先比较两个字符串中的第一个字符,如果相等则继续比较下一个字符,依次比较下去,直到两个字符串中的字符不相等时,其比较结果就是两个字符串的比较结果,两个字符串中的所有后续字符将不再被比较。
比较原理:
两个字符进行比较时,比较的是其ordinal value(原始值),调用内置函数ord可以得到指定字符的ordinal value。与内置函数ord对应的是内置函数chr,调用内置函数chr时指定ordinal value可以得到其对应的字符。
print('apple'>'app')#True
print('apple'>'banana')#False
print(ord('a'),ord('b'))#97 98
print(ord('杨'))#26472
print(chr(97),chr(98))#a b
print(chr(26472))#杨
'''==与is的区别'''
##==比较的是值是否相等
##is比较的是id是否相等
a=b='Python'
c='Python'
print(a==b)#True
print(b==c)#True
print(a is b)#True
print(a is c)#True
print(id(a))
print(id(b))
print(id(c))#a,b,c指向的是同一个内存空间
4、字符串的切片操作
字符串是不可变类型:
不具备增、删、改等操作
切片操作将产生新的对象
s='hello,Python'
s1=s[:5] #由于没有指定起始位置,所以从0开始
s2=s[6:]#由于没有指定结束位置,所以切到字符串的结束
s3='!'
newstr=s1+s3+s2
print(s1)#hello
print(s2)#Python
print(newstr)#hello!Python
print(id(s))
print(id(s1))
print(id(s2))
print(id(s3))
print(id(newstr))
#切片[start:end:step]
print(s[1:5:1])#ello #从1开始截到5,不包括5,步长为1
print(s[::2])#hloPto
print(s[::-1])#nohtyP,olleh #默认从字符串最后一个元素开始,到字符串的第一个元素结束,因为步长为负数
print(s[-6::1])#Python 从索引为-6开始到字符串的最后一个元素结束,步长为1
5、格式化字符串
格式化字符串的两种方式:
%作占位符:
%s----->字符串
%i或%d----->整数
%f------>浮点数
{}作占位符
name='张三'
age=20
#一、%占位符
print('我叫%s,今年%d岁' % (name,age))#我叫张三,今年20岁
#二、{}占位符
print('我叫{0},今年{1}岁'.format(name,age))#我叫张三,今年20岁
#三、f-string
print(f'我叫{name},今年{age}岁')#我叫张三,今年20岁
print('%d' % 99)#99
print('%10d' % 99)# 99###10表示的是宽度
print('%f' % 3.1415926)#3.1415926 #表示的是精度
print('%.3f' % 3.1415926)#3.142
#可以同时表示宽度和精度
print('%10.3f' % 3.1415926)# 3.142##总宽度为10,小数点后3位
print('{0}'.format(3.1415926))#3.1415926
print('{0:.3}'.format(3.1415926))#3.14#'.3'表示一共是三位数,‘0’表示的是占位符的顺序,也可以省略不写
print('{0:.3f}'.format(3.1415926))#3.142#'.3'表示是三位小数
print('{:10.3f}'.format(3.1415926))# 3.142#'.3'表示是三位小数,同时设置宽度和精度,一共是10位
6、字符串的编码转换
编码与解码的方式:
编码:将字符串转换为二进制数据(bytes)
解码:将bytes类型的数据转换成字符串类型
s='天涯共此时'
#编码
print(s.encode(encoding='GBK'))#GBK编码格式中一个中文占两个字节
print(s.encode(encoding='UTF-8'))#UTF-8编码格式中一个中文占三个字节
#解码
byte=s.encode(encoding='GBK')
print(byte.decode(encoding='GBK'))#byte代表就是一个二进制数据(字节类型的数据) #天涯共此时
print(byte.decode(encoding='UTF-8'))#报错 编码格式要与解码格式相同
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)#30
res=calc(b=10,a=20)#根据等号左侧变量的名字传递参数值,等号左侧变量的名称称为关键字参数
print(res)#30 #a=20,b=10
2、函数的参数传递
函数调用的参数传递:
位置实参:
根据形参对应的位置进行实参传递
关键字实参:
根据形参名称进行实参传递
函数调用的参数传递内存分析图:
def fun(arg1,arg2):
print('arg1=',arg1)#11
print('arg2=',arg2)#[22,33,44]
arg1=100
arg2.append(10) ##追加个10
print('arg1=',arg1)#100
print('arg2=',arg2)#[22,33,44,10]
n1=11##不可变
n2=[22,33,44]##列表是可变序列
print(n1)#11
print(n2)#[22,33,44]
fun(n1,n2)
print(n1)#11
print(n2)#[22,33,44,10]
#在函数调用过程中,进行参数传递
'''如果是不可变对象,在函数体内的修改不会影响实参的值 arg1的修改不会影响n1的值
如果是可变对象,在函数体内的修改会影响到实参的值 arg2的修改会影响n2的值
'''
实际参数和形式参数的名称可以不相同
3、函数的返回值
函数返回多个值时,结果为元组
def fun(num):
odd=[]#存奇数
even=[]#存偶数
for i in num:
if i%2:
odd.append(i)
else:
even.append(i)
return odd,even
print(fun([10,29,34,23,44,53,55]))
###([29,23,53,55],[10,34,44])
'''函数的返回值
(1)如果函数没有返回值(函数执行完毕之后,不需要给调用处提供数据)return可以省略不写
(2)函数的返回值,如果是1个,直接返回原类型
(3)函数的返回值,如果是多个,返回的结果为元组
'''
def fun1():
print('hello')
fun1()
def fun2():
return 'hello'
res=fun2()
print(res)
def fun3():
return 'hello','world'
res=fun3()
print(res)##('hello','world') #结果为一个元组
'''函数在定义时是否需要返回值,视情况而定'''
4、函数的参数定义
函数定义默认值参数:
函数定义时,给形参设置默认值,只有与默认值不符的时候才需要传递实参
def fun(a,b=10): #b=10为默认值参数
print(a,b)
fun(100)#100传送给a,b=10
fun(20,30)#a=20,b=30
print('hello')
print('world')'''
hello
world'''#默认换行输出
print('hello',end='\t')
print('world')'''hello world'''#不换行了
个数可变的位置参数:
定义函数时,可能无法事先确定传递的位置实参的个数时,使用可变的位置参数
使用*定义个数可变的位置参数
结果为一个元组
def fun(*args) #函数定义时的可变的位置参数
print(args)
fun(10)#(10,)
fun(10,30)#(10,30)
fun(30,40,50)#(30,40,50)
def fun1(**args)
print(args)
fun1(a=10)#{'a':10}
fun1(a=20,b=30,c=40)#{'a':20,'b':30,'c':40}
'''def fun2(*args,*a)
pass
以上代码程序会报错,个数可变的位置参数只能是一个'''
'''def fun2(**args,**args2)
pass
以上代码程序会报错,个数可变的关键字参数也只能是一个'''
def fun2(*args1,**args2)##可行
pass
def fun2(**args3,*args4)##不可行,报错
pass
'''在一个函数的定义过程当中,既有个数可变的关键字形参,也有个数可变的位置形参,要求个数可变的位置形参放在个数可变的关键字形参之前'''
个数可变的关键字参数:
定义函数时,无法事先确定传递的关键字实参的个数时,使用可变的关键字形参
使用**定义个数可变的关键字形参
结果为一个字典
函数参数总结:
def fun(a,b,c)#a,b,c在函数的定义处,所以是形参
print('a=',a)
print('b=',b)
print('c=',c)
#函数调用
fun(10,20,30)#函数调用的时候的参数传递,是位置传参
lst=[11,22,33]
####fun(lst)##程序报错,三个参数只传递了一个
fun(*lst)##在函数调用时,将列表的每个元素都转换为位置实参传入
fun(a=100,c=300,b=200)#函数调用,是关键字实参
dic={'a':111,'b':222,'c':333}
##fun(dic)####程序报错,三个参数只传递了一个missing 2
fun(**dic)##在函数调用时,将字典的每个键值对都转换为关键字实参传入
def fun(a,b=10)#b在函数的定义处,所以是形参,而且进行了赋值,b称为默认值形参
print('a=',a)
print('b=',b)
def fun2(*args)#个数可变的位置形参
print(args)
def fun3(*args2)#个数可变的关键字形参
print(args2)
fun2(10,20,30,40)
fun3(a=11,b=22,c=33,d=44,e=55)
def fun4(a,b,c,d)
print('a=',a)
print('b=',b)
print('c=',c)
print('d=',d)
#调用fun4
fun4(10,20,30,40) #位置实参传递
fun4(a=10,b=20,c=30,d=40)#关键字实参传递
fun4(10,20,c=30,d=40) #前两个参数采用位置实参传递,后两个采用的是关键字实参传递
'''需求:c,d只能采用关键字实参传递'''
def fun4(a,b,*,c,d)#从*之后的参数,在函数调用时只能采用关键字参数传递
print('a=',a)
print('b=',b)
print('c=',c)
print('d=',d)
##fun4(10,20,30,40) #报错
fun4(a=10,b=20,c=30,d=40)#关键字实参传递
fun4(10,20,c=30,d=40)
'''函数定义时的形参的顺序问题'''
def fun5(a,b,*,c,d,**args)#可行
pass
def fun6(*args,**args2)#可行
pass
def fun7(a,b=10,*args,**args2)#可行
pass
5、变量的作用域
变量的作用域:
程序代码能访问该变量的区域
根据变量的有效范围可分为:
-
局部变量:
在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量就会变成全局变量
-
全局变量:
函数体外定义的变量,可作用于函数内外
def fun(a,b)
c=a+b#c就是局部变量,在函数体内定义的变量,a,b为函数的形参,作用范围也是函数内部,相当于局部变量
print(c)
'''
print(c)
print(a)'''#报错,因为a,c超出了作用域
name='杨老师'#name的作用范围为函数内部和外部都可以使用,是全局变量
print(name)
def fun2()
print(name)
#调用函数
fun2()
def fun3()
global age=20#函数内部定义的局部变量加上global,变成了全局变量
print(age)
fun3()
print(age)
6、递归函数
递归函数:
如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数
递归的组成部分:
递归调用与递归终止条件
递归的调用过程:
每递归调用一次函数,都会在栈内存分配一个栈帧
每执行完一次函数,都会释放相应的空间
递归的优缺点:
缺点:占用内存多,效率低下
优点:思路和代码简单
def fac(n)
if n==1:
return 1
else:
res=n*fac(n-1)
return res
print(fac(6))
斐波那契数列:
1 1 2 3 5
第一项=1
第二项=1
第三项=第一项+第二项
第四项=第三项+第二项
def fib(n)#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))'''
1
1
2
3
5
8'''
全民来找茬
1、Bug的由来和分类
Debug:为程序调节错误
-
Bug常见类型:
1>粗心导致的语法错误SyntaxError
粗心导致错误的自查宝典:
1、漏了末尾的冒号,如if语句,循环语句,else子句等
2、缩进错误,该缩进的没缩进,不该缩进的瞎缩进
3、把英文符号写成中文符号,比如说:引号,冒号,括号
4、字符串拼接的时候,把字符串和数字拼在一起
5、没有定义变量,比如说while的循环条件的变量
6、“==”比较运算符和“=”赋值运算符的混用
#粗心导致的语法错误SyntaxError
#(1)
age=input('请输入你的年龄')
print(type(age))
###if age>=18:
### print('成年人...')
#解决方案:
if int(age)>=18:
print('成年人...')
#(2)
#while i<10:
# print(i)#没有给i赋值
#解决方案:
i=0
while i<10:
print(i)
i+=1
**2>知识不熟练导致的错误:**
(1)索引越界问题IndexError
(2)append()方法使用掌握不熟练
lst=[11,22,33,44]#列表的索引从0开始
#print(lst[4])#错误
print(lst[3])#正确
lst=[]
#lst=append('A','B','C')#append()方法没有指明是谁的,而且append()方法一次只能添加一个
lst.append('A')
lst.append('B')
lst.append('')
print(lst)
**3>思路不清导致的问题解决方案:**
(1)使用print()函数
(2)使用"#"暂时注释部分代码
4>被动掉坑:程序代码逻辑没有错,只是因为用户错误操作或者一些“例外情况”而导致的程序崩溃
被动掉坑问题的解决方案:
Python提供了异常处理机制,可以在异常出现时及时捕获,然后内部“消化”,让程序继续运行
多个except结构:
捕获异常的顺序按照先子类后父亲类的顺序,为了避免遗漏可能出现的异常,可以在最后增加BaseException
try:
n1=int(input('请输入一个整数'))
n2=int(input('请输入另一个整数'))
result=n1/n2
print('',result)
except ZeroDivisionError:
print('除数不能为0')
except ValueError:
print('不能将字符串转换为数字')
except BaseException as e:
print(e)
2、不同异常类型的处理方式
3、异常处理机制
try…except…else结构:
如果try 块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块
try:
n1=int(input('请输入一个整数'))
n2=int(input('请输入另一个整数'))
result=n1/n2
except BaseException as e:
print('出错了',e)
else:
print('计算结果为:',result)
**try...except...else...finally结构:**
finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源
try:
n1=int(input('请输入一个整数'))
n2=int(input('请输入另一个整数'))
result=n1/n2
except BaseException as e:
print('出错了',e)
else:
print('计算结果为:',result)
finally:
print('无论是否产生异常,总会被执行的代码')
print('程序结束')
异常类型 | 描述 |
---|---|
ZeroDivisionError | 除(或取模)零(所有数据类型) |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
NameError | 未声明/初始化对象(没有属性) |
SyntaxError | Python语法错误 |
ValueError | 传入无效的参数 |
#数学运算异常ZeroDivisionError
print(10/0)
#IndexError
lst=[11,22,33,44]
print(lst[4])
#KeyError
dic={'name':'张三','age':20}
print(dic['gender'])
#NameError
print(num)
#SyntaxError
int a=20#python中变量是没有数据类型的
#ValueError
a=int('hello')#hello不能转成十进制整数
traceback模块:
使用taceback模块打印异常信息
import traceback
try:
print('--------')#有时候在前输出,有时候在后,在中间
print(1/0)
except:
traceback.print_exc()
4、PyCharm的调试模式
断点:
程序运行到此处,暂时挂起,停止执行。此时可以详细观察程序的运行情况,方便做出进一步的判断
进入调试视图:
进入调试视图的三种方式:
(1)单击工具栏上的按钮
(2)右键单击编辑区:点击:debug’模块名’
(3)快捷键shift+F9
找对象不积极思想有问题
1、两大编程思想
区别:
面向过程 | 面向对象 |
---|---|
事物比较简单,可以用线性的思维去解决 | 事物比较复杂,使用简单的线性思维无法解决 |
共同点:
面向过程和面向对象都是解决实际问题的一种思维方式
总:
二者相辅相成,并不是对立的
解决复杂问题,通过面向对象方式便于我们从宏观上把握事物之间复杂的关系、方便我们分析整个系统;具体到围观操作,仍然使用面向过程方式来处理
2、类和对象的创建
类:类别,分门别类
类是多个类似事物组成的群体的统称。能够帮助我们快速理解和判断事物的性质
数据类型:
不同的数据类型属于不同的类
使用内置函数查看数据类型
print(type(100))#<class 'int'>
对象:
Python中一切皆对象
类的创建:
创建类的语法:
class Student :
pass
类的组成:
类属性
实例方法
静态方法
类方法
class Student:#Student 类名是由一个或多个单词组成,要求每个单词的首字母大写,其余小写
pass
# Python中一切皆对象,Student是对象吗?内存有开空间吗? 是,是类对象
print(id(Student))#开辟内存地址了
print(type(Student))#<class 'type'>
print(Student)#<class '__main__.Student'>
对象:
id(内存空间)、type(类型) 、值
class Student:
native_place='吉林' #直接写在类里的变量叫做类属性
#初始化方法#############################################
def __init__(self,name,age):##赋值操作
self.name=name #self.name称为实体属性,在这里进行了赋值操作,将局部变量name的值赋值给实体属性
self.age=age
#实例方法
def eat(self):##self可以换成别的单词,写也得写,不写也得存在
print('学生在吃饭')
#在类之外定义的称为函数,在类之内定义的叫做方法
#静态方法@staticmethod修饰的方法
@staticmethod
def method(): #不允许使用self
print('我使用了staticmethod修饰,所以我是静方法')
#类方法classmethod修饰的方法
@classmethod
def cm(cls):##cls类方法
print('我是类方法,因为我使用了classmethod进行修饰')
#函数
def drink():
print('喝水')
对象的创建:
对象的创建又称为类的实例化
语法:
实例名 = 类名 ()
意义:有了实例,就可以调用类中的内容
class Student:
native_place='吉林' #直接写在类里的变量叫做类属性
#初始化方法#############################################
def __init__(self,name,age):##赋值操作
self.name=name #self.name称为实体属性,在这里进行了赋值操作,将局部变量name的值赋值给实体属性
self.age=age
#实例方法
def eat(self):##self可以换成别的单词,写也得写,不写也得存在
print('学生在吃饭')
#在类之外定义的称为函数,在类之内定义的叫做方法
#静态方法@staticmethod修饰的方法
@staticmethod
def method(): #不允许使用self
print('我使用了staticmethod修饰,所以我是静方法')
#类方法classmethod修饰的方法
@classmethod
def cm(cls):##cls类方法
print('我是类方法,因为我使用了classmethod进行修饰')
#函数
def drink():
print('喝水')
#创建Student类的对象
stu1=Student('张三',20)
print(id(stu1))
print(type(stu1))#<class '__main__.Student'>
print(stu1)
#####类对象
print(id(Student))
print(type(Student))#<class 'type'>
print(Student)#<class '__main__.Student'>
#根据类对象创建出来的是实例对象
class Student:
native_place='吉林' #直接写在类里的变量叫做类属性
#初始化方法#############################################
def __init__(self,name,age):##赋值操作
self.name=name #self.name称为实体属性,在这里进行了赋值操作,将局部变量name的值赋值给实体属性
self.age=age
#实例方法
def eat(self):##self可以换成别的单词,写也得写,不写也得存在
print('学生在吃饭')
#在类之外定义的称为函数,在类之内定义的叫做方法
#静态方法@staticmethod修饰的方法
@staticmethod
def method(): #不允许使用self
print('我使用了staticmethod修饰,所以我是静方法')
#类方法classmethod修饰的方法
@classmethod
def cm(cls):##cls类方法
print('我是类方法,因为我使用了classmethod进行修饰')
#函数
def drink():
print('喝水')
#创建Student类的对象
stu1=Student('张三',20)
stu1.eat()#学生在吃饭 #对象名.方法名()
print(stu1.name)#张三
print(stu1.age)#20
print('-----------')
Student.eat(stu1)#学生在吃饭 与stu1.eat()代码功能相同,都是调用Student中的eat功能 #类名.方法名(类的对象名) --->实际上就是方法定义处的self
3、类对象与类属性
类属性:类中方法外的变量称为类属性,被该类的所有对象所共享
4、类方法与静态方法
类方法:使用@classmethod修饰的方法,使用类名直接访问的方法
静态方法:使用@staticmethod修饰的方法,使用类名直接访问的方法
class Student:
native_place='吉林' #直接写在类里的变量叫做类属性
#初始化方法#############################################
def __init__(self,name,age):##赋值操作
self.name=name #self.name称为实体属性,在这里进行了赋值操作,将局部变量name的值赋值给实体属性
self.age=age
#实例方法
def eat(self):##self可以换成别的单词,写也得写,不写也得存在
print('学生在吃饭')
#在类之外定义的称为函数,在类之内定义的叫做方法
#静态方法@staticmethod修饰的方法
@staticmethod
def method(): #不允许使用self
print('我使用了staticmethod修饰,所以我是静方法')
#类方法classmethod修饰的方法
@classmethod
def cm(cls):##cls类方法
print('我是类方法,因为我使用了classmethod进行修饰')
#类属性的使用方式
print(Student.native_pace)
stu1=Student('张三',30)
stu2=Student('李四',30)
print(stu1.native_pace)#吉林
print(stu2.native_pace)#吉林
Student.native_pace='天津'
print(stu1.native_pace)#天津
print(stu2.native_pace)#天津
#####类方法的使用方式,类名去调用
Student.cm()
#####静态方法的使用方式,类名去调用
Student.method()
动态绑定属性和方法:
Python是动态语言,在创建对象之后,可以动态地绑定属性的方法
class Student:
def __init__(self,name,age):##__init中的属性是stu1,stu2所共有的
self.name=name
self.age=age
def eat(self):
print(self.name+'在吃饭')
stu1=Student('张三',20)
stu2=Student('李四',30)
#一个Student类可以创建N多个Student类的实例对象,每个实例对象的属性值可以不同
print(id(stu1))
print(id(stu2))
#只想给给李四添加一个性别,为stu2动态绑定性别属性
stu1.gender='女'
print(stu1.name,stu1.age,stu1.gender)#张三 20 女
print(stu2.name,stu2.age,stu2.gender)#stu1没有gender属性,报错
print('--------')
stu1.eat()
stu2.eat()
#为stu1单独绑定show方法
def show():
print('定义在类之外的,称为函数')
stu1.show=show
stu1.show()
stu2.show()#报错,因为stu2并没有绑定show方法
接着找对象
1、封装
面向对象的三大特征:
封装:提高程序的安全性
将数据(属性)和行为(方法)包装到类对象中。在方法内部对属性进行操作,在类对象的外部调用方法。这样,无需关心方法内部的具体实现细节,从而隔离了复杂度。
在Python中没有专门的修饰符用于属性的私有,如果该属性不希望在类对象外部被访问,前边使用两个“_”。
继承:提高代码的复用性
多态:提高程序的可扩展性和可维护性
class Car:
def __init__(self,brand):
self.brand=brand
def start(self):
print('汽车已启动')
car=Car('宝马X5')
car.start()
print(car.brand)
封装的实现:
class Student:
def __init__(self,name,age):
self.name=name
self.__age=age##age不希望在类外部被使用,所以加了两个'_',但是可以在类的内部使用
def show(self):
print(self.name,self.__age)
stu.Student('张三',20)
stu.show()
#在类的外部使用name与age
print(stu.name)
print(stu.__age)#显示stu对象没有'__age'这样的属性
#不希望被使用,但是可以使用
print(dir(stu))
print(stu._Student__age) #20 #在类的外部可以通过'_Student__age'访问
2、继承
语法格式:
class 子类类名 ( 父类1,父类2,…) :
pass
如果一个类没有继承任何类,则默认继承object
Python支持多继承
定义子类时,必须在其构造函数中调用父类的构造函数
class Person(object)#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_no):
super().__init__(name,age)
self.stu_no=stu_no
class Teacher(Person):
def __init__(self,name,age,teachofyear):
super().__init__(name,age)
self.teachofyear=teachofyear
stu=Student('张三',20,'1001')
teacher=Teacher('李四',34,10)
stu.info()#张三 20
teacher.info()#李四 34
class A(object):
pass
class B(object):
pass
class C(A,B):#多继承
pass
3、方法重写
如果子类对继承自父类的某个属性或者方法不满意,可以在子类中对其(方法体)进行重新编写
子类重写后的方法中可以通过super().xxx()调用父类中被重写的方法
class Person(object)#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_no):
super().__init__(name,age)
self.stu_no=stu_no
def info(self):#重写Person类中的方法
super().info()#调用父类info,输出name,age
print(self.stu_no)
class Teacher(Person):
def __init__(self,name,age,teachofyear):
super().__init__(name,age)
self.teachofyear=teachofyear
def info(self):#重写Person类中的方法
super().info()#调用父类info,输出name,age
print(self.teachofyear)
stu=Student('张三',20,'1001')
teacher=Teacher('李四',34,10)
stu.info()'''张三 20
1001'''
teacher.info()'''李四 34
10'''
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):#重写__str__()方法,用于返回对象的描述
return '我的名字是{0},今年是{1}岁',format(self.name,self.age)
stu=Student('张三',20)
print(dir(stu))
print(stu)#stu的内存地址 ##重写之后输出:我的名字是张三,今年是20岁 #默认调用__str__()方法,默认输出字符串
print(type(stu))#<class '__main__.Student'>
5、多态
简单地说,多态就是“具有多种形态”,它指的是:即使不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法
class Animal(object):
def eat(self):
print('动物会吃')
class Dog(Animal):
def eat(self):
print('狗吃骨头')
class Cat(Animal):
def eat(self):
print('猫吃鱼')
class Person(object):
def eat(self):
print('人吃五谷杂粮')
#定义函数
def fun(obj):
obj.eat
#开始调用函数
fun(Cat())
fun(Dog())
fun(Animal())
fun(Person())###鸭子类型
静态语言与动态语言:
静态语言实现多态的三个必要条件:(Java)
1>继承
2>方法重写
3>父类引用指向子类对象
动态语言的多态崇尚“鸭子类型”当看到一只鸟走起来像鸭子、游泳起来像鸭子、收起来也像鸭子,那么这只鸟就可以被称为鸭子。在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为。(Python)
6、特殊方法和特殊属性
特殊属性:
dict 获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法:
len() 通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
add() 通过重写__add__()方法,可以使用自定义对象具有“+”功能
new() 用于创建对象
init() 对创建的对象进行初始化
class A:
pass
class B:
pass
class C(A,B):
def __init__(self,name,age):
self.name=name
self.age=age
#创建C类的对象
x=C('Jack') #x是C类的一个实例对象
print(x.__dict__)#{'name':'Jack','age':20} #实例对象的属性字典
print(C.__dict__)#类对象的属性和方法字典
print(x.__class__)#输出对象所属的类型 <class '__main__.C'>
print(C.__bases__)#输出C类的父类类型的元组
print(C.__base__)#输出离C最近的父类,谁写在前面输出谁,即类的基类
print(C.__mro__)#输出类的层次结构
print(A.__subclasses__())#查看A的子类的列表
a=20
b=100
c=a+b#两个整数类型的对象的相加操作
d=a.__add__(b)
print(c)#120
print(d)#120
'''class Student:
def __init__(self,name):
self.name=name
stu1=Student('张三')
stu2=Student('李四')
s=stu1+stu2
print(s)#报错,不能相加'''
#若非得想让它们相加
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('Jack')
stu2=Student('李四')
s=stu1+stu2#实现了两个对象的加法运算,因为在Student类中编写了__add__()方法
print(s)#Jack李四
s=stu1.__add__(stu2)
print(s)#Jack李四
lat=[11,22,33,44]
print(len(lst))#4#内置函数len,可以计算出列表的长度
print(lst.__len__())#4
print(len(stu1))#4
class Person(object):
def __new__(cls,*args,**args):#创建对象
print('__new__被调用执行了,cls的id值为{0}'.format(id(cls)))
obj=super().__new__(cls)
print('创建的对象的id为:{0}'.format(id(obj)))
return obj
def __init__(self,name,age):
print('__init__被调用了,self的id值为:{0}'.format(id(self)))
self.name=name
self.age=age
print('object这个类对象的id为:{0}'.format(id(object)))
print('Person这个类对象的id为:{0}'.format(id(Person)))
#创建Person类的实例对象
p1=Person('张三',20)
print('p1这个Person类的实例对象的id为:{0}'.format(id(p1)))
类的浅拷贝与深拷贝:
变量的赋值操作:
只是形成两个变量,实际上还是指向同一个对象
浅拷贝:
Python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象
深拷贝:
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象,源对象和拷贝对象所有的子对象也不相同
百宝箱
1、什么叫模块
Modules
函数与模块的关系:
一个模块中可以包含N多个函数
在Python中一个扩展名为.py的文件就是一个模块
使用模块的好处:
方便其他程序和脚本的导入并使用
避免函数名和变量名冲突
提高代码的可维护性
提高代码的可重用性
模块中包含函数和类和语句
2、自定义模块
创建模块:
新建一个.py文件,名称尽量不要与Python自带的标准模块名称相同
导入模块:
import 模块名称 [as 别名]
from 模块名称 import 函数/变量/类
#导入模块中的所有 #导入自定义的模块时如果不可用需要调试:在目录下右键找到MarkDirectory as---Sources Root
import math
print(id(math))
print(type(math))
print(math)
print(math.pi)
print(dir(math))
print(math.pow(2,3),type(math.pow(2,3)))#8.0 float
#导入模块中的指定内容
from math import pi#只导入了math中的pi
print(pi)
3、以主程序的形式执行
在每个模块的定义中都包括一个记录模块名称的变量__name__,程序可以检查该变量,以确定他们在哪个模块中执行。如果一个模块不是被导入到其他程序中执行,那么它可能在解释器的顶级模块中执行。顶级模块的__name__变量的值为__main__
if name = ‘main’ :
pass ##只有当点击运行本.py时,才会执行运算
4、python中的包
包是一个分层次的目录结构,它将一组功能相近的模块组织在一个目录下
作用:
代码规范
避免模块名称冲突
包与目录的区别:
包含__init__.py文件的目录称为包
目录里通常不包含__init__.py文件
包的导入:
import 包名.模块名
5、第三方模块的安装及使用
第三方模块的安装:
pip install 模块名
第三方模块的使用:
import 模块名
大宝藏
1、编码格式介绍
Python的解释器使用的是Unicode(内存)
.py文件在磁盘上使用UTF-8存储(外存)
2、文件的读写原理
文件的读写俗称“IO操作”
文件读写流程:
Python操作文件–>打开或新建文件–>读、写文件–>关闭资源
操作原理:
3、文件读写操作
内置函数open()创建文件对象
语法规则:
file=open('a.txt','r')
print(file.readlines())
file.close()
4、文件对象常用的方法
常用的文件打开模式
文件的类型:
按文件中数据的组织形式,文件可以分为一下两大类:
文本文件:存储的是普通“字符”文本,默认为unicode字符集,可以使用记事本程序打开
二进制文件:把数据内容用“字节”进行存储,无法用记事本打开,必须使用专用的软件打开,eg:mp3音频文件,jpg图片,.doc文档等
5、with语句(上下文管理器)
with语句可以自动管理上下文资源,不论什么原因跳出with块,都能确保文件正确的关闭,以此来达到资源释放的目的
6、目录操作
os模块是Python内置的与操作系统功能和文件系统相关的模块,该模块中的语句的执行结果通常与操作系统有关,在不同的操作系统上运行,得到的结果可能不一样。
os模块与os.path模块用于对目录或文件进行操作。