Python基础

409 阅读49分钟

一、输入输出函数(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\')

三、二进制与字符编码

image.png

四、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(): 将其它类型转为浮点类型

image.png

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. 运算符优先级

()>算术运算符>位运算符>比较运算符>布尔运算符>赋值运算符

总结一(一到六)

image.png

image.png

七、程序的组织结构

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)
结果为51
for i in range(5):
    for j in range(1,11):
        if j%2==0:
            continue
        print(j,end='\t')
    print()

结果为51 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对象的三种方式

  1. range(stop)——>创建一个(0,stop)间的整数序列,从0开始,步长为1
  2. range(start,stop)—>创建一个(start,stop)之间的整数序列,从start开始,步长为1
  3. 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

总结二(七到十)

image.png

image.png

十一、列表

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]

总结image.png

十二、字典

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}

总结

image.png

十三、元组

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、如果元组中的对象是可变对象,则可变对象的引用不允许改变,但数据可以改变

image.png

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}

总结

image.png

十五、字符串

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. 字符串的常用操作

image.png

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

image.png

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

image.png

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

image.png

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']

image.png

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

image.png

3. 字符串的比较

image.png

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. 格式化字符串

image.png

#格式化字符串  
#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. 字符串的编码转换

image.png

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'))#天涯共此时 解码

总结三(十一到十五)

字符串总结

image.png

列表、字典、元组、集合总结

image.png

十六、函数

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  
    在一个函数的定义过程中,既有个数可变的关键字形参,也有个数可变的位置形参  
    要求,个数可变的位置形参放在个数可变的关键字形参之前  
'''                                               

image.png

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])))

总结(十六)

image.png

十七、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

总结(十七)

image.png

十八、类与对象

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()

总结(十八)

image.png

十九、面向对象

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

总结(十九)

image.png

二十、模块

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  模块名
    

总结(二十)

image.png

二十一、文件操作

1. 编码格式介绍

image.png

encoding = gbk(默认utf-8)

2. 文件的读写原理

  • 文件的读写俗称‘IO操作’

  • 文件读写操作流程

        Python操作文件——》打开或新建文件——》读、写文件——》关闭资源
    
  • 内置函数open( )创建文件对象,通过IO流将磁盘文件的内容和程序中的对象中的内容进行同步

image.png

语法规则

file = open (filename  [,mode,encoding])
其中,mode:打开模式,默认为只读;
     encoding:默认文本文件中字符的编写格式为gbk

3. 文件读写操作

image.png

file=open('a.txt','r')
print(file.readlines())
file.close()

file=open('b.txt','w')
file.write('helloworld')
file.close()

4. 文件对象常用的方法

image.png

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')#调用计算器

image.png

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)

image.png

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))

总结(二十一)

image.png