Python学习——基础知识
一. 初识Python
-
第一个Python程序:打开cmd命令提示符程序,输入python并回车;出现三个向右的箭头(>>>),然后在里面输入代码(print(“Hello World!!!”))回车可立即执行。
-
小练习: print("零基础,学Python,月薪过万,就来黑马程序员。‘’)。
-
Python解释器运行Python文件:可以将代码,写入一个以".py"结尾的文件中,使用python命令去运行它。
在Windows系统的D盘中新建一个名为test.py的文件,并通过记事本程序打开它,输入以下内容:
print(“学Python,来黑马!!!”)
print(“月薪过万。”)
-
在命令提示符窗口中,输入:python d:\test.py。
-
Python最常见的开发软件:PyCharm软件PyCharm需要以"工程"为单元,供我们使用。想要写代码需要先创建一个工程。
二. Python基础语法
1. 字面量
(1) 字面量:在代码中,被写下来的固定的值,称之为字面量
(2) Python中常用的6种值(数据)的类型:
(3) 字符串:又称文本,是由任意数量的字符如中文、英文、各类符号、数字等组成。所以叫做字符的串,Python中,字符串需要用双引号(" ")包围起来,被引号包围起来的,都是字符串。
(4) 实例:写在print语句中的依旧是字面量
print(13.14) 输出整数10
print(666) 输出浮点数13.14
print("黑马程序员") 输出字符串
2. 注释
2.1 注释的作用
(1) 注释:在程序代码中对程序代码进行解释说明的文字。
(2) 作用:不能被执行,只是对程序代码进行解释说明,让别人能看懂程序代码的作用,能够大大增强程序的可读性。
2.2 注释的分类
(1) 单行注释:以 # 开头,# 右边的所有文字当做说明。** #号和注释内容一般建议以一个空格隔开 **。
(2) 多行注释:以 一对三个双引号 引起来(“”“注释内容”“”)来解释说明一段代码的作用使用方法。
3. 变量
3.1 变量的概念
(1) 变量:在程序运行时,能储存计算结果或能表示值的抽象概念。变量名,也就是变量本身。
# 定义一个变量,用来记录钱包余额
money = 50
#通过print语句,输出变量记录的内容
print("钱包还有:",money)
# 买了一个冰淇淋,花费10元
money=money-10
print("买了冰淇淋后,钱包还有:",money,"元")
3.2 变量的使用
(1) 格式:变量名 = 变量值
- 在Python中,定义变量时不需要显式地指定变量的类型。Python是一种动态类型语言,它会根据赋给变量的值来自动推断变量的类型。这意味着你可以直接对变量赋值,而无需指定其类型。
(2) 特征:变量的值可以改变。
(3) print语句如何输出多份内容:print(内容1,内容2,… , 内容n)。
(4) Python中使用 加(+)、减(-)、乘(*)、除(/) 即可完成各种运算。
4. 数据类型
- 变量无类型,而数据有类型
4.1 type()语句 —— 有返回值 有结果
(1) 可以通过type()语句来得到数据的类型:type(被查看类型的数据)
(2) 在print语句中,直接输出类型语句信息
print(type(13.14))
print(type(666))
print(type("黑马程序员"))
结果:
<class 'float'>
<class 'int'>
<class 'str'>
(2) 用变量存储type()的结果(返回值)
string_type = type("黑马程序员")
int_type = type(666)
float_type = type(13.14)
print(string_type)
print(int_type)
print(float_type)
结果:
<class 'str'>
<class 'int'>
<class 'float'>
(3) 查看变量中存储的数据类型
通过type(变量)可以输出类型,这是查看变量存储的数据的类型。因为,变量无类型,但是它存储的数据有。
name = "黑马程序员"
name_type = type(name) //用变量接收type()的结果/返回值
print(name_type)
结果:
<class 'str'>
5. 数据类型转换
5.1 数据类型转换的意义
(1) 从文件中读取的数字,默认是字符串,我们需要转换成数字类型
(2) 后续学习的input()语句,默认结果是字符串,若需要数字也需要转换
(3) 将数字转换成字符串用以写出到外部系统
5.2 常见的转换语句/函数
(1) int(x):将x转换为一个整数
# 将字符串转换为整型
str_int=int("12")
print(type(str_int),str_int)
结果:
<class 'int'> 12
#浮点数转整数 —— 损失精度,不会四舍五入,直接丢掉小数部分
float_int=int(13.645)
print(type(float_int),float_int)
结果:
<class 'int'> 13
(2) floa(x):将x转换为一个浮点数
#将字符串转成浮点型
str_float=float("12.345")
print(type(str_float),str_float)
结果:
<class 'float'> 12.345
# 整数转浮点数
int_float=float(13)
print(type(int_float),int_float)
结果:
<class 'float'> 13.0
- 万物皆可转字符串,但要将字符串转成数字类型,前提是该字符串内的内容必须都是数字。
(3) str(x):将x转换为字符串
# 将数字类型转换为字符串
num_str=str(11)
print(type(num_str),num_str)
结果:
<class 'str'> 11
- 这三个语句,都是带有结果的(返回值),可以用print直接输出,或者用变量存储结果值。
6. 标识符
6.1 什么是标识符
(1) 定义:是用户在编程时所使用的一系列名字,用于给变量、类、方法等命名。
6.2 标识符命名规则
(1) 内容限定——只允许出现:英文、中文、数字、下划线(_) 这四类元素,其余任何内容都不被允许。中文不推荐,数字不可以开头。
(2) 大小写敏感——是能够完全区分大小写的。
(3) 不可使用关键字——Python中有一系列单词,称之为关键字,关键字在Python中都有特定用途。
- 在Python中,有以下关键字:
False
: 表示假的布尔值。True
: 表示真的布尔值。None
: 表示空值或缺失的值。and
: 逻辑与运算符。or
: 逻辑或运算符。not
: 逻辑非运算符。if
: 条件语句的关键字,用于执行条件判断。else
: 条件语句的关键字,在if语句的条件不满足时执行的分支。elif
: 条件语句的关键字,用于在多个条件之间进行判断。for
: 循环语句的关键字,用于迭代遍历一个序列或集合。while
: 循环语句的关键字,用于在条件满足时一直执行代码块。break
: 用于中断循环并跳出循环体。continue
: 用于中断当前循环的迭代,并进入下一次循环迭代。def
: 定义函数的关键字。return
: 用于从函数中返回结果。import
: 导入模块或库的关键字。from
: 从某个模块中导入具体的函数或对象。as
: 用于给导入的模块或对象起别名。try
: 异常处理语句的关键字,尝试执行可能会发生异常的代码块。except
: 异常处理语句的关键字,用于捕获并处理异常。finally
: 异常处理语句的关键字,在try和except之后执行,无论是否有异常发生。assert
: 断言关键字,用于断定某个条件是真的,否则会引发异常。with
: 上下文管理器的关键字,用于简化资源的管理。class
: 定义类的关键字。pass
: 用于占位,表示空操作。global
: 声明全局变量的关键字。nonlocal
: 声明非局部变量的关键字(在嵌套函数中使用)。yield
是Python中的关键字,用于定义生成器函数。
# 规则1,内容限定,限定只能使用:中文、英文、数字、下划线,注意:不能以数字作为开头
# 1_name="张三" 错误代码示范
# name_!='张三' 错误代码示范
# 规则2,大小写敏感
Item="黑马程序员"
item=666
print(Item,item)
# 规则3,不可使用关键字
# 错误示例,使用了关键字:class=1
# 错误示例,使用了关键字:def=1
Class=1
print(Class)
6.3 变量命名规范
(1) 见名知意 :
- 明了:尽量做到,看到名字,就知道是什么意思
- 简洁:尽量在确保"明了"的前提下,减少名字的长度
(2) 下划线命名法 :
- 多个单词组合变量名,要使用下划线做分隔
(3) 英文字母全小写 :
- 命名变量中的英文字母,应该全部小写
7. 运算符
7.1 算术(数学)运算符
(1)
# 算术(数学)运算符
print("1+1=",1+1)
print("2-1=",2-1)
print("3*3=",3*3)
print("11/2=",11/2)
print("11//2=",11//2)
print("9%2=",9%2)
结果:
1+1= 2
2-1= 1
3*3= 9
11/2= 5.5
11//2= 5
9%2= 1
7.2 赋值运算符
(1) 赋值运算符
(2) 复合赋值运算符
# 赋值运算符
num=1+2*3
# 复合赋值运算符
num1=1
num1+=1 # 结果:num=num+1=1+1=2
print("num1+=1:",num1)
num1-=1 # 结果:num=num-1=2-1=1
print("num1-=1:",num1)
num1*=4
print("num1*=4:",num1)
num1/=2
print("num1/=2:",num1)
num1=3
num1%=2
print("num1%=2:",num1)
num1**=2
print("num1**=2:",num1)
num1=9
num1//=2
print("num1//=2:",num1)
结果:
num1+=1: 2
num1-=1: 1
num1*=4: 4
num1/=2: 2.0
num1%=2: 1
num1**=2: 1
num1//=2: 4
7.3 位运算符
(1) 位运算符是指:位与&、位或|、位异或^、位取反~、左移位<<、右移位>>等运算符。
(2) Python位运算符主要针对整数类型的数据来操作的,首先把要运算的整数类型的数据转换为二进制形式后再按位进行相关计算。按位运算符是把数字看作二进制来进行计算的。
7.4 逻辑运算符
(1) 逻辑运算符有三种:and(与)、or(或)、not(非)。
(2) 逻辑运算符的优先级:>not>and>or。
8. 字符串扩展
8.1 字符串的三种定义方式
(1) 单引号定义法:name=‘人生’
(2) 双引号定义法:name=“人生”
(3) 三引号定义法:name=“”" 人生 “”‘’ —— 和多行注释的写法一样,同样支持换行操作;使用变量去接收它,它就是字符串;不使用变量接收它,就可以作为多行注释。
# 单引号定义法,
name = '人生'
print(type(name),name)
# 双引号定义法
name="人生"
print(type(name),name)
# 三引号定义法
name="""人生"""
print(type(name),name)
结果:
<class 'str'> 人生
<class 'str'> 人生
<class 'str'> 人生
(4) 字符串的引号嵌套:如果想要定义的字符串本身是包含:单引号、双引号自身。
- 单引号定义法:可以内含双引号
- 双引号定义法:可以内含单引号
- 可以使用转义字符()来将引号解除效用,变成普通字符串
# 在字符串中,包含双引号
name = ' "人生" '
print(name)
# 在字符串中,包含单引号
name=" '人生' "
print(name)
# 使用转义字符\解除引号的效用
name=" \"人生\" "
print(name)
结果:
"人生"
'人生'
"人生"
8.2 字符串拼接
(1) 如果有两个字符串(文本)字面量,可以将其拼接成一个字符串,通过+号即可完成,如:print(“人生”+“大事”) —— 人生大事。
(2) 一般,字面量和变量或者变量和变量之间会进行拼接。
# 字符串字面量之间的拼接
print("人生"+"大事") —— 人生大事
# 字符串字面量和字符串变量的拼接
name="人生"
address="大事"
tel=400901
print("我的"+name+",我的"+address+"我的电话:"+tel) #不能成功执行,因为tel不是字符串
(3) 注意:
- 只能适用于字符串类型本身
- 无法和非字符串类型进行拼接
8.3 字符串格式化
(1) 定义:先占个位置,等有变量,再把它变成字符串放到占位的位置
(2) %s:将内容转换成字符串,放入占位位置
# 通过占位的形式,完成数字和字符串的拼接
# %表示要占位,s表示将变量变成字符串要放入的地方
class_num=57
avg_salary=16781
message="北京%s期,毕业平均工资为:%s"%(class_num,avg_salary)
print(message)
结果:
北京57期,毕业平均工资为:16781
-
多个变量占位,变量要用括号括起来,每个变量用逗号隔开,并按照占位的顺序填入
-
数字也能用%s占位,将数字转换为字符串去完成拼接。
(3) %d:将内容转换成整数,放入占位位置
(4) %f:将内容转换成浮点型,放入占位位置
# 通过%d和%f完成占位
name="传智播客"
setup_year=2006
stock_price=19.9
message="%s,成立于:%d,我今天的股价是:%f"%(name,setup_year,stock_price)
print(message)
结果:
传智播客,成立于:2006,我今天的股价是:19.900000
8.4 格式化的精度控制
(1) 数字精度控制:使用辅助符号"m.n"来控制数据的宽度和精度,小数点和小数部分也算入宽度计算。
- m,控制宽度,要求是数字(很少使用),设置的宽度小于数字自身,不生效
- .n,控制小数点精度,要求是数字,会进行小数的四舍五入
- %5d:表示将整数的宽度控制在5位,如数字11,就会变成:[][][ ] [ ] [ ]11,用3个空格补足宽度
- %7.2f:小数点和小数部分也算入宽度计算。表示将宽度控制为5,将小数点精度设置为2。如浮点数11.345,结果是:[] [] 11.35。两个空格补足宽度,小数部分限制2位精度,四舍五入为.35
- %.2f:表示不限制宽度,只设置小数点精度为2,如11.345结果为:11.35
num1=11
num2=11.345
print("数字11宽度限制5,结果是:%5d"%num1)
print("数字11宽度限制1,结果是:%1d"%num1) # 11比宽度1大,宽度不生效
print("数字11.345宽度限制7,小数精度2,结果是:%7.2f"%num2)
print("数字11.345宽度不限制,小数精度2,结果是:%.2f"%num2)
结果:
数字11宽度限制5,结果是: 11 # 3个空格补足
数字11宽度限制1,结果是:11
数字11.345宽度限制7,小数精度2,结果是: 11.35 # 2个空格补足
数字11.345宽度不限制,小数精度2,结果是:11.35
(2) 快速字符串格式化:
- 语法:f’‘内容{变量}’'的格式来快速格式化。f:format
- 不限数据类型,不做精度控制,原样输出
- 适合对精度没有要求的时候快速使用
# 快速格式化 —— 不限数据类型,不做精度控制,原样输出
name="传智播客"
setup_year=2006
stock_price=19.9
print(f"我是{name},我成立于:{setup_year},我今天的股票价格是:{stock_price}")
结果:
我是传智播客,我成立于:2006,我今天的股票价格是:19.9
8.5 对表达式进行格式化
(1) 表达式:一条具有明确执行结果的代码语句。 如,1+1 ,5*2。在变量定义的时候,如:age=11+11,等号右侧就是表达式,也就是有具体的结果,将结果赋给了等号左侧的变量。
(2) 在无需使用变量进行数据存储的时候,可以直接格式化表达式,简化代码。
- f"{表达式}"
- “%s%d%f”%(表达式,表达式,表达式)
print("1 * 1的结果是:%d"%(1*1))
print(f"1 * 2的结果是:{1*2}")
print("字符串在Python中的类型名是:%s"%type("字符串"))
print("智者不入爱河,建设%s,我今年%d岁,我希望我的薪资是%8.2f"%("美丽中国",20,30000.877))
结果:
1 * 1的结果是:1
1 * 2的结果是:2
字符串在Python中的类型名是:<class 'str'>
智者不入爱河,建设美丽中国,我今年20岁,我希望我的薪资是30000.88
9. 数据输入
9.1 获取键盘输入
(1) input语句(函数)
- 使用input()语句可以从键盘获取输入
- 使用一个变量接收(存储)input语句获取的键盘输入数据即可
print("请告诉我你是谁?")
name=input()
print("原来你的的名字是:%s"%name)
结果:
请告诉我你是谁?
蒲一永 # 这是自己输入的内容
原来你的的名字是:蒲一永
(2) input()语句其实是可以在要求使用者输入内容之前,输出提示内容的
- name = input(“请告诉我你是谁?”)
name = input("请告诉我你是谁?")
print("我知道啦,你是:%s"%name)
结果:
请告诉我你是谁? 曹光砚
我知道啦,你是: 曹光砚
(3) 输入数字类型
- 因为无论键盘输入什么类型的数据,获取到的数据永远都是字符串类型。可以进行类型转换
# 输入数字类型
num=input("请告诉我你的银行卡密码:")
print("你的银行卡密码的类型是:",type(num)) #不管输入什么类型,输入的都是字符串str类型
# 数据类型转换
num=int(num)
print("你的银行卡密码的类型是:",type(num))
结果:
请告诉我你的银行卡密码:124
你的银行卡密码的类型是: <class 'str'>
你的银行卡密码的类型是: <class 'int'>
三. Python判断语句
1. 布尔类型和比较运算符
(1) 布尔类型的实质
- 布尔表达现实生活中的逻辑,即真和假。True表示真,False表示假。True本质上是一个数字记作1,False记作0。
(2) 布尔类型的定义
- 定义变量存储布尔类型数据:变量名称 = 布尔类型字面量
- 布尔类型不仅可以自行定义,同时也可以通过计算得来。也就是使用比较运算符进行比较得到布尔类型的结果。
(3) 比较运算符
str1="itcast"
str2="itheima"
print(f"itcast <= ithemia 结果是:{str1<=str2}")
num1=10
num2=15
print(f"10 != 10的结果是:{num1!=num2}")
结果是:
itcast <= ithemia 结果是:True
10 != 15的结果是:True
2. if语句的基本格式
(1) if 要判断的条件:
条件成立时,要做的事情
- 第二行要缩进4个空格,通过缩进判断归属于哪个if
- 判断语句的结果,必须是布尔类型True或者False,True会执行if内的代码语句,False则不会执行
- 判断条件之后的 : 冒号
age=2
print(f"今年我已经{age}岁了")
if age>=18:
print("我已经成年了") # 前面有4个空格
print("即将步入大学生活") # 这两行归属于if判断的代码语句块,需在前方填充4个空格缩进
print("时间过得真快") # 不属于if
结果:
今年我已经2岁了
时间过得真快
age=20
print(f"今年我已经{age}岁了")
if age>=18: # 条件成立,会执行以下两句
print("我已经成年了") # 前面有4个空格
print("即将步入大学生活")
print("时间过得真快") # 不属于if
结果:
今年我已经20岁了
我已经成年了
即将步入大学生活
时间过得真快
3. if else 语句
(1) if 条件:
满足条件时要做的事1
满足条件时要做的事2
满足条件时要做的事3
…
else:
不满足条件时要做的事1
不满足条件时要做的事2
不满足条件时要做的事3
…
- else 的代码块,同样要4个空格作为缩进
print("欢迎来到儿童游乐场,儿童免费,成人收费")
age=input("请输入你的年龄: ")
age=int(age) # 注意将字符串转换为数字类型
if age>=18:
print("您已成年,游玩需要补票10元。")
else:
print("您未成年,可以免费游玩")
print("祝您游玩愉快")
4. if elif else语句
(1) 某些场景下,判断条件不止一个,可能有多个,if elif else语句可以实现
(2) if 条件1:
条件1满足应做的事情
条件1满足应做的事情
…
elif 条件2:
条件2满足应做的事情
条件2满足应做的事情
…
elif 条件n:
条件n满足应做的事情
条件n满足应做的事情
…
else:
所有条件都不满足应做的事情
所有条件都不满足应做的事情
…
(3) 注意:
- 多条件判断下,判断是互斥且有顺序的。
- if条件满足,将不会执行elif和else;elif条件1满足,将不会执行其他elif条件和else条件;if条件、elif条件均不满足,将会执行else语句。
- elif语句可以写多个,else语句可以省略不写,效果等同于几个独立的if判断。
- 空格多斤同样不可省略。
if int(input("请输入你的身高(cm):"))<120:
print("您的身高未超出120cm,可以免费游玩")
elif int(input("请输入你的VIP级别(1-5):"))>3:
print("您的VIP级别大于3,可以免费游玩")
elif int(input("请输入今天的日期(1-30):"))==1:
print("今天是1号免费日,可以免费游玩")
else:
print("不好意思,所有条件都不满足,需要购票10元")
print("祝您游玩愉快")
这样的话,当第一个身高条件满足,则不会执行后面的输入VIP等级以及日期的判断语句,直接跳出判断。
5. 判断语句的嵌套
(1) 不仅是多个并列条件,还会有满足前置条件才会二次判断的多层判断需求。
(2) 自由组合if elif else,完成待定需求的要求。
(3) if 条件1:
满足条件1做的事情1
满足条件1做的事情2
if 条件2:
满足条件2做的事情1
满足条件2做的事情2
- 如上式,第二个if,属于第一个if内,只有第一个if满足条件,才会执行第二个if
- 嵌套的关键点,在于:空格缩进,通过空格缩进,来决定语句之间的:层次关系
print("欢迎来到动物园")
if int(input("输入你的身高:"))>120:
print("你的身高大于120cm,不可以免费")
print("不过如果你的VIP等级高于3,可以免费游玩")
if int(input("请告诉我你的VIP等级:"))>3:
print("恭喜你,你的vip等级大于3,可以免费游玩")
else:
print("Sorry,你需要补票10元")
else :
print("欢迎小朋友免费进行游玩")
age=20
join_year=3
level=1
if age>=18:
print("你是成年人")
if age<30:
print("你的年龄达标了")
if join_year>2:
print("恭喜你年龄和入职时间都达标,可以领取")
elif level>3:
print("恭喜你年龄和级别都达标,可以领取")
else:
print("不好意思,尽管年龄达标,但是入职时间和级别都不达标")
else:
print("不好意思,年龄太大了")
else:
print("不好意思,年龄太小了")
结果:
你是成年人
你的年龄达标了
恭喜你年龄和入职时间都达标,可以领取
四. Python循环语句
1. while循环的基础用法
(1) 格式:
while 条件:
条件满足时,做的事情1
条件满足时,做的事情2
条件满足时,做的事情3
…
- 只要条件满足,会无限循环执行
- while的条件需要得到布尔类型,True表示继续循环,False表示结束循环
- 需要设置循环终止的条件
- 空格缩进和if判断一样,都需要设置
i=0
while i<5:
print("我很厉害")
i+=1
结果:
我很厉害
我很厉害
我很厉害
我很厉害
我很厉害
(2) # *设置一个范围1-100的随机整数变量,通过while循环,配合input语句,判断输入的数字是否等于随机数
**“”"***1.无限次机会,直到猜中为止
**2.每一次猜不中,都会提示大了小了
**3.猜完数字之后,提示猜了几次
*“”"
# 通过一个布尔类型的变量,做循环是否继续的标记
flag=True
count=0
while flag:
guess_num = int(input("请输入你猜的数字(1-100):"))
count+=1
if guess_num==num:
print("猜对啦")
flag=False
else:
if guess_num>num:
print("你的猜大了")
else:
print("你的猜小了")
print(f"你总共猜测了{count}次")
2 . while循环的嵌套用法
(1) while 条件1:
条件1满足时,做的事情1
条件1满足时,做的事情2
条件1满足时,做的事情3
…
while 条件2:
条件2满足时,做的事情1
条件2满足时,做的事情2
条件2满足时,做的事情3
…
(2) 注意点:
- 循环语句的嵌套,要注意空格缩进,基于空格缩进进行决定层次关系
- 注意条件的设置,避免出现无限循环
(3) 打印九九乘法表
# 打印九九乘法表
# 控制行的循环 i<=9 ;控制每一行的输出 j<=i
i=1
while i<=9:
j=1
while j<=i:
print(f"{j}*{i}={i*j}\t",end='')
j+=1
print()
i+=1
结果:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
3. 补充知识
(1) print输出不换行** —— 在print语句中,加上end=''即可输出不换行了
- print(“Hello”,end=‘’)
(2) 制表符\t,效果等同于在键盘上按下"tab键",它可以让我们的多行字符串对齐
# print输出不换行
print("Hello",end='')
print("World",end='')
print()
# 制表符\t ,进行字符串的对齐
print("Hello\tWorld")
print("ithemia\tbest")
结果:
HelloWorld
Hello World
ithemia best
4. for循环的基础用法
(1) for循环是一种"轮询"机制,是对一批内容进行"逐个处理"
(2) 语法:
for 临时变量 in 待处理数据集:
循环满足条件时执行的代码
# 遍历字符串 取出一个个字符
name = "itheima"
for x in name:
print(x)
结果:
i
t
h
e
i
m
a
(3) 注意:
- 同while循环不同,for循环是无法定义循环条件的,只能从被处理的数据集中,依次取出内容进行处理。
- 理论上讲,Python的for循环无法构建无限循环(被处理的数据集不可能无限大)。
- 循环内的语句,需要有空格缩进。
(4) range语句:
①语法中的待处理数据集,严格来说,称之为:序列类型。序列类型指的是,其内容可以一个个依次取出的一种类型,包括:
- 字符串
- 列表
- 元组
- 等
②语法1:range(num) —— 获取一个从0开始,到num结束的数字序列(不含num本身)。如range(5)获得的数据是:[0,1,2,3,4]。
③语法2:range(num1,num2) —— 获取一个从num1开始,到num2结束的数字序列(不含num2本身)。如range(5,10)获得的数据是:[5,6,7,8,9]。
④语法3:range(num1,num2,step) —— 获取一个从num1,到num2结束的数字序列(不含num2本身),数字之间的步长,以step为准(step默认为1)。如range(5,10,2)获得的数据是:[5,7,9]。
# range语句 配合for循环使用
"""从0开始,到10结束,不包含10"""
for x in range(10):
print(x)
print("********")
"""从5开始,到10结束,不包含10"""
for x in range(5,10):
print(x)
print("********")
"""从5开始,到10结束,不包含10,数字之间的间隔是2"""
for x in range(5,10,2):
print(x)
结果:
0
1
2
3
4
5
6
7
8
9
********
5
6
7
8
9
********
5
7
9
(5) 临时变量作用域
- 将从数据集序列中取出的数据赋给:临时变量x,只限定在for循环内部。
- 实际上是可以访问到的
- 不建议这么做
解决方案:在for循环前,把临时变量定义好
i=0
for i in range(3):
print(i)
print(i)
5. for循环的嵌套应用
(1) 语法:
for 临时变量 in 待处理数据集(序列):
循环满足条件时应做的事情1
循环满足条件时应做的事情2
循环满足条件时应做的事情n
…
for 临时变量 in 待处理数据集(序列):
循环满足条件时应做的事情1
循环满足条件时应做的事情2
循环满足条件时应做的事情n
…
# 坚持表白100天,每天10朵花
i=1
for i in range(1,101):
print(f"今天是表白的第{i}天")
for j in range(1,11):
print(f"送给她的第{j}朵花")
print(f"我喜欢你的第{i}天结束")
print(f"第{i}天,表白成功")
6. 循环中断:continue和break
(1) Python中提供continue和break关键字用以对循环进行临时跳过和直接结束。
(2) continue关键字用于:中断本次循环,直接进入下一次循环
for i in range(1,6):
print("语句1")
continue
print("语句2")
结果:
语句1
语句1
语句1
语句1
语句1
- continue关键字只可以控制:它所在的循环临时中断
(3) break关键字用于:直接结束循环
# break
for i in range(1,6):
print("语句1")
break
print("语句2")
print("语句3")
结果:
语句1
语句3
五. Python函数
1. 函数介绍
(1) 函数:是组织好的,可重复使用的,用来使用特定功能的代码段。
- 将功能封装在函数内,可供随时随地重复利用
- 提高代码的复用性,减少重复代码,提高开发效率
# 需求:统计字符串的长度,且不使用内置函数len()
str1="itheima"
str2="itcast"
str3="python"
def my_len(data):
count=0
for i in data:
count+=1
print(f"字符串{data}的长度是{count}")
my_len(str1)
my_len(str2)
my_len(str3)
结果:
字符串itheima的长度是7
字符串itcast的长度是6
字符串python的长度是6
2. 函数的定义
(1) 语法:
def 函数名(传入参数):
函数体
return 返回值
(2) 函数的调用: 函数名(传入参数)
def say_hi():
print("hello")
say_hi()
结果:
hello
(3) 注意:
- 执行顺序时从上向下,函数必须先定义后使用。
- 参数如不需要,可以省略;返回值如不需要,可以省略。
3. 函数的参数
(1) 传入参数的功能是:在函数进行计算的时候,接受外部(调用时)提供的数据。
# 定义相加的函数
def add(x,y):
result=x+y
print(f"{x}+{y}的计算结果是:{result}")
# 调用函数,传入被计算的2个数字
add(5,6)
结果:
5+6的计算结果是:11
- 函数定义中,提供的x和y,称为形式参数(形参),表示函数声明将要使用2个参数:参数之间用逗号隔开。
- 函数调用中,提供的5和6,称为实际参数(实参),表示函数执行时真正使用的参数值:传入的时候,按照顺序传入数据,使用逗号隔开。
- 传入参数的数量是不受限制的,传入参数时,要和形式参数一一对应,逗号隔开。
4. 函数的返回值
(1) 语法:
def 函数名(传入参数):
函数体
return 返回值
变量 = 函数(参数)
# 定义一个函数,完成两数相加的功能
def add(a,b):
result=a+b
return result
# 返回结果后,还想输出一句话 return后面的代码都不会执行了
print("我完事了")
# 函数的返回值,可以通过变量去接收
r=add(2,2)
print(r)
结果:
4
- 使用return关键字来返回结果。
- 函数体在遇到return后就结束了,所以写在return后的代码不会执行。
(2) 函数返回值之None类型
- 用在函数无返回值上:无返回值的函数,实际上就是返回了一个特殊的字面量None,其类型是:<class ‘NoneType’>,也就是返回了空的意思。
- 用在if判断上:在if判断中,None等同于False;一般用于在函数中主动返回None,配合if判断做相关处理。
- 用于声明无内容的变量上:定义变量,但暂时不需要变量有具体值,可以用None来代替。name = None
# 返回None类型
def say_hi():
print("Hello")
res=say_hi()
print(res)
print(type(res))
结果:
Hello
None
<class 'NoneType'>
# None用于if判断
def check_age(age):
if age>18:
return "SUCCESS"
else:
return None
result=check_age(16)
if not result:
# 进入if表示result是None值,也就是False
print("未成年,不可以进入")
结果:
未成年,不可以进入
5. 函数说明文档
(1) 给函数添加说明文档,辅助理解函数的作用。
(2) 语法:
def func(x,y):
“”"
函数说明
:param x:形参x的说明
:param y:形参y的说明
:return:返回值的说明
“”"
函数体
return 返回值
# 定义函数,进行文档说明
def add(x,y):
"""
# 自动补全
add函数可以接收2个参数,进行两数相加的功能
:param x: 形参x表示相加的其中一个数字
:param y: 形参y表示相加的另一个数字
:return: 返回值是两数相加的结果
"""
result=x+y
print(f"两数相加的结果是:{result}")
return result
(3) 在PyCharm编写代码是,可以通过鼠标悬停,查看调用函数的说明文档。
6. 函数的嵌套调用
(1) 定义:函数的嵌套调用指的是一个函数里面又调用了另一个函数。
# 定义函数func_b
def func_b():
print("----2----")
# 定义函数func_a,并在内部调用func_b
def func_a():
print("----1----")
# 嵌套调用func_b
func_b()
print("----3----")
func_a()
结果:
----1----
----2----
----3----
(2) 如果函数a中,调用了另一个函数b,那么先把函数b中的任务都执行完毕后才会回到上次函数a执行的位置,完成后,继续执行函a剩余的内容。
7. 变量的作用域
(1) 变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用),主要分为两类:局部变量和全局变量。
(2) 局部变量:定义在函数体内部的变量,即只在函数体内部生效。作用:在函数体内部,在函数运行时临时保存数据,当函数调用完成之后,立刻销毁了局部变量。
# 演示局部变量
def test_c():
num=100
print(num)
test_a()
# 出了函数体,局部变量就无法使用了
# print(num)
(3) 全局变量:指的是在函数体内、外都能生效的变量。如果有一个数据,在函数a和函数b中都要使用,就可以将这个数据存储在一个全局变量中。定义这个变量在函数的外部。
# 演示全局变量
num=200
def test_a():
print(f"test_a:{num}")
def test_b():
print(f"test_b:{num}")
test_a()
test_b()
print(num)
结果:
test_a:200
test_b:200
200
(4) global关键字:可以在函数内部声明变量为全局变量。
# 使用global关键字,在函数内声明变量为全局变量
num=200
def test_a():
print(f"test_a:{num}")
def test_b():
global num
num=500
print(f"test_b:{num}")
test_a()
test_b()
print(num) # 输出的是500
8. 综合案例
六. Python数据容器
1. 数据容器入门
(1) 数据容器:一个容器可以容纳多份数据。
(2) 定义:一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素,每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。
(3) 数据容器根据特点的不同,如:
- 是否支持重复元素
- 是否可以修改
- 是否有序,等
分为5类,分别是:列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)。
2. 数据容器
2.1 列表 list [ ]
(1) 基本语法:
- 字面量:[元素1,元素2,元素3,元素4,…]
- 定义变量: 变量名称 = [元素1,元素2,元素3,元素4,…]
- 定义空列表:变量名称 = [ ] ; 变量名称 = list ( )
列表内的每一个数据,称之为元素。以[ ] 作为标识,列表内每一个元素之间用逗号, 隔开。
# 定义一个列表list
name_list=["itheima","itcast","python"]
print(name_list)
print(type(name_list))
my_list=["itheima",666,True]
print(my_list)
print(type(my_list))
结果:
['itheima', 'itcast', 'python']
<class 'list'>
['itheima', 666, True]
<class 'list'>
(2) 注意:
- 列表可以一次存储多个数据,且可以为不同的数据类型,支持嵌套。
# 定义一个嵌套的列表
my_list2=[[1,2,3],[4,5,6]]
print(my_list2)
print(type(my_list2))
结果:
[[1, 2, 3], [4, 5, 6]]
<class 'list'>
(3) 列表的下标(索引):使用[ ]
- 正向:列表中的每一个元素,都有其位置下表索引,从前向后的方向,从0开始,依次递增。
- 反向:反向索引,也就是从后向前,从-1开始,依次递减(-1,-2,-3,…)。
- 嵌套列表的索引:同样支持下标索引。列表名[1][0]
# 列表[下表索引],从前向后,从0开始,每次+1 从后向前,从-1开始,每次-1
print(my_list[0]) # Tom
print(my_list[1]) # Lily
print(my_list[2]) # Rose
# 错误示范:通过下标索引取出数据,一定不要超出范围
# print(my_list[3]) # 超出范围,数组越界
# 通过下标索引取出数据(倒序取出)
print(my_list[-1]) # Rose
print(my_list[-2]) # Lily
print(my_list[-3]) # Tom
# 取出嵌套列表的元素
my_list = [[1,2,3],[4,5,6]]
print(my_list[1][1]) # 5
(4) 列表的常用操作(方法):
在Python中,如果将函数定义为class(类)的成员,那么函数会称之为:方法。
方法和函数功能一样,有传入参数,有返回值,只是方法的使用格式不同:
- 函数的使用:num=add(1,2)
- 方法的使用: student = Student() num=student.add(1,2)
① 列表的查询功能(方法):
-
查找某元素的下标:查找指定元素在列表的下标,如果找不到,报错ValueError。
—— 语法:列表.index(元素)。index就是列表对象(变量)内置的方法(函数)。
-
统计列表内,有多少元素:
—— 语法:len(列表)。
② 列表的修改功能(方法):
-
修改特定位置(索引)的元素值:直接对指定下标(正向、反向下标均可)的值进行重新赋值(修改)。
—— 语法:列表[下标] = 值。
-
插入元素:在指定的下标位置,插入指定的元素。
—— 语法:列表.insert(下标,元素)。
-
追加元素:将指定元素,追加到列表的尾部。
—— 语法1:列表.append(元素)。
—— 语法2:列表.extend(其他数据容器)。将其它数据容器的内容取出,依次追加到列表尾部。
-
删除元素:
—— 语法1:del 列表[下标]。
—— 语法2:列表.pop(下标)。
-
删除某元素在列表中的第一个匹配项:
—— 语法:列表.remove(元素)。
-
清空列表内容:
—— 语法:列表.clear( )。
-
统计某元素在列表内的数量:
—— 语法:列表.count(元素)。
(5) 列表的特点: -
可以容纳多个元素。
-
可以容纳不同类型的元素(混装)。
-
数据是有序存储的(有下标序号)。
-
允许重复数据存在。
-
可以修改(增加或者删除等)。
(6) 列表的遍历:
① while循环:定义一个变量表示下标,从0开始,循环条件为下标值<列表的元素数量,使用列表[下标]的方式取出。
def list_while_func():
"""
使用while循环遍历列表的演示函数
:return: None
"""
mylist=["传智教育","黑马程序员","Python"]
index=0
while index<len(mylist):
element=mylist[index]
print(f"列表的元素{index+1}:{element}")
index+=1
list_while_func()
② for循环:从容器内,依次取出元素并赋值到临时变量上。在每一次的循环中,我们可以对临时变量(元素)进行处理。
def list_for_func():
"""
使用for循环遍历列表的演示函数
:return: None
"""
mylist=[1,2,3,4,5]
for element in mylist:
print(f"列表的元素有:{element}")
list_for_func()
③ 两者对比:
- 在循环控制上:
- while循环可以自定循环条件,并自行控制
- for循环不可以自定循环条件,只能一个个从容器内取出数据
- 在无限循环上:
- while循环可以通过条件控制做到无限循环
- for循环理论上不可以,因为被遍历的容器容量不是无限的
- 在使用场景上:
- while循环适用于任何想要循环的场景
- for循环适用于,遍历数据容器的场景或者简单的固定次数循环场景
2.2 元组 tuple ( )
(1) 列表是可以修改的,如果想要传递的信息不被篡改,就需要元组。
元组一旦定义完成,就不可修改。
(2) 基本语法:定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同类型的
- 元组字面量:(元素,元素,元素,…)
- 元组变量:变量名称 = (元素,元素,元素,…)
- 空元祖:变量名称 = ( ) ; 方式1 变量名称 = tuple ( ) ;方式2,实际上是得到元组的类对象
t1=(1,"Hello",True)
t2=()
t3=tuple()
print(f"t1的类型是:{type(t1)},内容是:{t1}")
print(f"t2的类型是:{type(t2)},内容是:{t2}")
print(f"t3的类型是:{type(t3)},内容是:{t3}")
- 当元组只有一个数据,这个数据后面要添加逗号
# 定义单个元素的元组
t4=("hello",)
print(f"t4的类型是:{type(t4)},内容是:{t4}")
结果:
t4的类型是:<class 'tuple'>,内容是:('hello',)
- 元组的嵌套:
# 元组的嵌套
t5=((1,2,3),(4,5,6))
print(f"t5的类型是:{type(t5)},内容是:{t5}")
结果:
t5的类型是:<class 'tuple'>,内容是:((1, 2, 3), (4, 5, 6))
(3) 元组的下标(索引):同列表list一样
(4) 元组的相关操作:
- index( ):查找某个数据,如果数据存在返回对应的下标,否则报错。
- count( ):统计某个数据在当前元组出现的次数。
- len(元组):统计元组内的元素个数。
- 元组不可修改,但是如果里面有列表是可以的。
# 元组内容不可以修改,但是元组中的列表可以
t6=(1,2,["itheima","itcast"])
t6[2][0]="tef"
t6[2][1]="redf"
print(f"t6的内容是:{t6}") # t6的内容是:(1, 2, ['tef', 'redf'])
(5) 元组的特点:
- 可以容纳多个数据。
- 可以容纳不同类型的数据(混装)。
- 数据是有序存储的(下标索引)。
- 允许重复数据存在。
- 不可以修改(增加或者删除元素等)。
- 支持for循环。
2.3 字符串 str " "
(1) 定义:字符串是字符的容器,一个字符串可以存放任意数量的字符。每一个字符就是一个元素,每一字符也有下标索引。
(2) 字符串的下标(索引):和其他容器一样:列表、元组一样,字符串也可以通过下标进行访问。
- 从前向后,下标从0开始
- 从后向前,下标从-1开始
(3) 同元组一样,字符串是一个:无法修改的容器。字符串的相关操作:
- 查找特点字符串的下标索引值:字符串.index(字符串)。
- 字符串的替换:字符串.repalce(字符串1,字符串2)。—— 将字符串内的全部内容字符串1替换为字符串2。不是修改字符串本身,而是得到了一个新字符串,实质上相当于返回了一个新的字符串。
# replace方法
new_my_str=my_str.replace("it","程序")
print(f"将字符串{my_str},进行替换之后得到:{new_my_str}")
结果:
将字符串itheima and itcast,进行替换之后得到:程序heima and 程序cast
- 字符串的分割:字符串.split(分隔符字符串)。 —— 按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中。字符串本身不变,而是得到了一个列表对象。
# split方法
my_str="hello python itheima and itcast"
my_str_list=my_str.split(" ") #按照空格划分,返回一个列表
print(f"将字符串{my_str}进行分割后,得到:{my_str_list},类型是:{type(my_str_list)}")
结果:
将字符串hello python itheima and itcast进行分割后,得到:['hello', 'python', 'itheima', 'and', 'itcast'],类型是:<class 'list'>
- 字符串的规整操作:—— 会得到一个新的字符串
- 去除前后空格:字符串.strip()。
- 去除前后指定字符串:字符串.strip(字符串)。
# strip方法
my_str=" itheima and itcast "
new_my_str=my_str.strip() #不传入参数,去除首尾空格
print(f"字符串{my_str}进行strip后,结果是:{new_my_str}")
my_str="12itheima and itcast21"
new_my_str=my_str.strip("12")
print(f"字符串{my_str}进行strip(‘12’)后,结果是:{new_my_str}")
# 并不是完全按照12来的,只要满足其中任意均可去除,实质上是按照每个字符来去除
结果:
字符串 itheima and itcast 进行strip后,结果是:itheima and itcast
字符串12itheima and itcast21进行strip(‘12’)后,结果是:itheima and itcast
- 统计字符串内某字符串的出现次数:字符串.count(字符串)。
- 统计字符串的字符个数(包括空格也是一个字符):len(字符串)。
(4) 字符串的特点:
- 只可以存储字符串
- 长度任意(取决于内存大小)
- 支持下标索引
- 允许重复字符串存在
- 不可以修改(增加或者删除元素等)
- 支持for循环
(5) 字符串大小比较:
- 字符串是按位比较,也就是一位位进行对比,只要有一位大,那么整体就大。
- 通过ASCII码表,确定字符对应的码值数字来确定大小。
2.4 集合 set { }
(1) 集合最主要的特点就是:不支持元素的重复(自带去重功能),并且内容无序。
(2) 基本语法:和列表、元组、字符串等定义基本相同:
- 定义集合字面量:{元素1,元素2,元素3,…,元素n}
- 定义集合变量:变量名称 = {元素1,元素2,元素3,…,元素n}
- 定义空集合:变量名称 = set( )
# 定义集合
my_set={"传智教育","黑马程序员","itheima","传智教育","黑马程序员","itheima","传智教育","黑马程序员","itheima"}
my_empty_set=set() #定义空集合
print(f"my_set的内容是:{my_set},类型是:{type(my_set)}") # 不能重复,内容无序
print(f"my_empty_set的内容是:{my_empty_set},类型是:{type(my_empty_set)}")
结果:
my_set的内容是:{'itheima', '传智教育', '黑马程序员'},类型是:<class 'set'>
my_empty_set的内容是:set(),类型是:<class 'set'>
(3) 因为集合是无序的,所以集合不支持:下标索引访问。但是集合和列表一样,是允许修改的。
-
集合的常用操作 —— 修改
- 添加新元素:集合.add(元素)。将指定元素,添加到集合内。
- 移除元素:集合.remove(元素)。将指定元素,从集合内移除。集合本身被修改,移除了元素。
- 从集合中随机取出元素:集合.pop()。从集合中随机取出一个元素。会得到一个元素的结果,同时集合本身被修改,元素被移除。
- 清空集合:集合.clear()。
- 取出2个集合的差集:集合1.difference(集合2)。取出集合1和集合2的差集(集合1有而集合2没有的)。得到一个新集合,集合1和集合2不变。
# 取出2个集合的差集 set1={1,2,3} set2={1,5,6} set3=set1.difference(set2) print(set3) #{2,3} 集合1有而集合2没有的
- 消除2个集合的差集:集合1.difference_update(集合2)。对比集合1和集合2,在集合1内,删除和集合2相同的元素。集合1被修改,集合2不变。
# 消除2个集合的差集 set1.difference_update(set2) print(set1) # {2,3} 没有了1,删除了相同的 print(set2) # {1, 5, 6} 集合2不变
- 2个集合合并:集合1.union(集合2)。将集合1和集合2合成新集合,有相同的只有一个。得到新集合,集合1和集合2不变,也不能保证新集合的顺序。
# 2个集合合并 set1={1,2,3} set2={1,5,6} set3=set1.union(set2) print(set3) # {1, 2, 3, 5, 6} 去重,只保留一个1
- 统计集合元素的数量:len(集合)。得到一个整数表示集合的元素数量。
(4) 集合的特点:
- 可以容纳多个数据
- 可以容纳不同类型的数据(混装)
- 数据是无序存储的(不支持下标索引)
- 不允许重复数据存在
- 可以修改(增加或删除元素等)
- 支持for循环
2.5 字典/映射 dict
(1) 使用字典,实现用Key取出Value的操作。定义:同样使用{},不过存储的是一个个的:键值对。
(2) 基本语法:
- 定义字典字面量:{key1:value1,key2:value2,…,keyn:valuen}
- 定义字典变量:my_dict(变量名)={key1:value1,key2:value2,…,keyn:valuen}
- 定义空字典:my_dict={ } ; my_dict=dict( )
(3) 字典数据的获取:字典同集合一样,不可以使用下标索引,但是字典可以通过Key值来取得对应的Value。
- 字典[Key]可以取到对应Value
# 从字典中基于Key获取Value
my_dict1={"王力宏":99,"周杰伦":88,"林俊杰":77}
score1=my_dict1["周杰伦"]
print(f"周杰伦的分数是:{score1}")
结果:
周杰伦的分数是:88
(4) 字典的嵌套:字典的Key和Value可以是任意数据类型(Key不可以为字典)。这就表明,字典是可以嵌套的。
# 定义嵌套字典
stu_score_dict = {
"王力宏":{
"语文":77,
"数学":66,
"英语":33
},"周杰伦":{
"语文":88,
"数学":86,
"英语":55
},"林俊杰":{
"语文":99,
"数学":96,
"英语":66
}
}
print(f"学生的考试信息是:{stu_score_dict}")
# 从嵌套字典中获取数据
# 查看周杰伦的语文成绩
zhou_chinese=stu_score_dict["周杰伦"]["语文"]
print(f"周杰伦的语文成绩是:{zhou_chinese}")
# 查看林俊杰的英语成绩
lin_english=stu_score_dict["林俊杰"]["英语"]
print(f"林俊杰的英语成绩是:{lin_english}")
结果:
学生的考试信息是:{'王力宏': {'语文': 77, '数学': 66, '英语': 33}, '周杰伦': {'语文': 88, '数学': 86, '英语': 55}, '林俊杰': {'语文': 99, '数学': 96, '英语': 66}}
周杰伦的语文成绩是:88
林俊杰的英语成绩是:66
(5) 字典的特点:
- 键值对的Key和Value可以是任意类型(Key不可为字典)
- 字典内Key不允许重复,重复添加等同于覆盖原有数据
- 字典不支持下标索引,而是通过Key检索Value
- 可以容纳多个数据
- 可以容纳不同类型的数据
- 每一份数据是Key-Value键值对
- 可以通过Key获取到Value,Key不可以重复(重复会覆盖)
- 不支持下标索引
- 可以修改(增加或者删除更新元素等)
- 支持for循环,不支持while循环
(6) 字典的常用操作:
- 新增元素:字典[Key]=Value。字典被修改,如果新增的元素不存在,直接新增了键值对。
- 更新元素:字典[Key]=Value。字典被修改,如果修改的元素存在,元素被更新,原有的数据被覆盖。
- 删除元素:字典.pop(Key)。获得指定的Key的Value,同时字典被修改,指定的Key的数据被删除。
- 清空元素:字典.clear()。
- 获取全部的key:字典.keys()。得到字典中全部的Key。
- 统计字典内的元素数量:len(字典)。
my_dict={"周杰伦":99,"林俊杰":88,"张学友":77}
# 新增元素
my_dict["张信哲"]=66
print(f"字典经过新增元素后,结果:{my_dict}")
# 更新元素
my_dict["周杰伦"]=33
print(f"字典经过更新元素后,结果:{my_dict}")
# 删除元素
zhou_score=my_dict.pop("周杰伦")
print(f"字典中被移除了一个元素,结果:{my_dict},周杰伦的考试分数:{zhou_score}")
# 清空元素
my_dict.clear()
print(f"字典被清空了,内容是:{my_dict}")
# 获取全部的key
my_dict={"周杰伦":99,"林俊杰":88,"张学友":77}
keys=my_dict.keys()
print(f"字典的全部keys是:{keys}")
# 遍历字典
# 方式1:通过获取全部的key来完成遍历
for key in keys:
print(f"字典的key是:{key} ",end="")
print(f"字典的value是:{my_dict[key]}")
# 方式2:直接对字典进行for循环
for key in my_dict: # 每一次循环取出的就是key
print(f"字典的key是:{key} ", end="")
print(f"字典的value是:{my_dict[key]}")
# 统计字典内的元素数量,len()函数
num=len(my_dict)
print(f"字典中的元素数量是:{num}")
结果:
字典经过新增元素后,结果:{'周杰伦': 99, '林俊杰': 88, '张学友': 77, '张信哲': 66}
字典经过更新元素后,结果:{'周杰伦': 33, '林俊杰': 88, '张学友': 77, '张信哲': 66}
字典中被移除了一个元素,结果:{'林俊杰': 88, '张学友': 77, '张信哲': 66},周杰伦的考试分数:33
字典被清空了,内容是:{}
字典的全部keys是:dict_keys(['周杰伦', '林俊杰', '张学友'])
字典的key是:周杰伦 字典的value是:99
字典的key是:林俊杰 字典的value是:88
字典的key是:张学友 字典的value是:77
字典的key是:周杰伦 字典的value是:99
字典的key是:林俊杰 字典的value是:88
字典的key是:张学友 字典的value是:77
字典中的元素数量是:3
3. 数据容器(序列)的切片操作
3.1 什么是序列
(1) 序列是指:内容连续、有序,可以使用下标索引的一类数据容器。列表、元组、字符串,均可以视为序列。
3.2 序列的常用操作 —— 切片
(1) 切片:从一个序列中,取出一个子序列。
(2) 语法:序列[起始下标:结束下标:步长]。 —— 表示从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列。
- 起始下标表示从何处开始,可以留空,留空视作从头开始。
- 结束下标(不含)表示何处结束,可以留空,留空视作截取到结尾。
- 步长表示,依次取元素的间隔:
- 步长1表示,一个个取元素
- 步长2表示,每次跳过1个元素取
- 步长n表示,每次跳过n-1个元素取
- 步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)
# 对list切片,从1开始,4结束,步长1
my_list=[0,1,2,3,4,5,6]
result1=my_list[1:4:1] # 步长默认是1,所以可以省略不写
print(f"结果1:{result1}")
# 对tuple进行切片,从头开始,到最后结束,步长1
my_tuple=(0,1,2,3,4,5,6)
result2=my_tuple[:] #起始和结束不写,表示从头到尾,步长为1可以省略
print(f"结果2:{result2}")
# 对str进行切片,从头开始,到最后结束,步长为2
my_str="0123456"
result3=my_str[::2]
print(f"结果3:{result3}")
# 对str进行切片,从头开始,到最后结束,步长-1
my_str="0123456"
result4=my_str[::-1] # 等同于将序列反转了
print(f"结果4:{result4}")
# 对列表进行切片,从3开始,到1结束,步长-1
my_list=[0,1,2,3,4,5,6]
result5=my_list[3:1:-1]
print(f"结果5:{result5}")
# 对元组进行切片,从头开始,到尾结束,步长-2
my_tuple=(0,1,2,3,4,5,6)
result6=my_tuple[::-2]
print(f"结果6:{result6}")
结果:
结果1:[1, 2, 3]
结果2:(0, 1, 2, 3, 4, 5, 6)
结果3:0246
结果4:6543210
结果5:[3, 2]
结果6:(6, 4, 2, 0)
4. 数据容器的通用操作
(1) 遍历
- 5类数据容器都支持for循环遍历
- 列表、元组、字符串支持while循环,集合、字典不支持(无法下标索引)
(2) 统计功能
- len(容器) —— 统计容器的元素个数
- max(容器) —— 统计容器的最大元素
- min(容器) —— 统计容器的最小元素
(3) 通用转换功能
- list(容器) —— 将给定容器转换为列表:字典转列表,将value全部舍弃,只留key。
- str(容器) —— 将给定容器转换为字符串
- tuple(容器) —— 将给定容器转换为元组
- set(容器) —— 将给定容器转换为集合
(4) 通用排序功能
- sorted(容器,reserve=True)。将给定容器进行排序。默认为False,从小到大升序排列。reverse=True表示降序
- 排序的结果会统统变成列表项。
# 进行容器排序
my_list=[3,1,2,5,4]
my_tuple=(3,1,2,5,4)
my_str="bdcefga"
my_set={3,1,2,5,4}
my_dict={"key3":1,"key1":2,"key2":3,"key5":4,"key4":5}
print(f"列表对象的排序结果:{sorted(my_list,reverse=True)}")
print(f"元组对象的排序结果:{sorted(my_tuple)}")
print(f"字符串对象的排序结果:{sorted(my_str)}")
print(f"集合对象的排序结果:{sorted(my_set)}")
print(f"字典对象的排序结果:{sorted(my_dict)}")
结果:
列表对象的排序结果:[5, 4, 3, 2, 1]
元组对象的排序结果:[1, 2, 3, 4, 5]
字符串对象的排序结果:['a', 'b', 'c', 'd', 'e', 'f', 'g']
集合对象的排序结果:[1, 2, 3, 4, 5]
字典对象的排序结果:['key1', 'key2', 'key3', 'key4', 'key5']
七. Python函数进阶
1. 函数多返回值
(1) 如果一个函数要有多个返回值,按照返回值的顺序,写对应顺序的多个变量接收即可。
(2) 变量之间用逗号隔开,支持不同类型的数据return。
def test_return():
return 1,"hello",True
x,y,z=test_return()
print(x,y,z)
结果:
1 hello True
2. 函数多种传参方式
(1) 函数参数种类:根据使用方式的不同,函数中有4种常见参数使用方式:
- 位置参数
- 关键字参数
- 缺省参数
- 不定长参数
(2) 位置参数:调用函数时根据函数定义的参数位置类传递参数。
- 传递的参数和定义的参数必须顺序及个数必须一致
(3) 关键字参数:函数调用时,通过"键=值"形式传递参数。
- 可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求
- 函数调用时,如果有位置参数,必须在关键字参数的前面,但关键字参数之间不存在先后顺序
(4) 缺省参数:也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。
- 当调用函数时,没有传递参数,就会默认是缺省参数对应的值
- 函数调用时,如果为缺省参数传值,则修改默认参数值,否则使用这个默认值
(5) 不定长参数:不定长参数也叫可变参数,用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。
-
当调用函数时不确定参数个数时,可以使用不定长参数
-
位置传递:
- 传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递
-
关键字传递:
- 参数是"键=值"形式的情况下,所有的"键=值"都会被kwargs接受,同时会根据"键=值"组成字典
# 不定长 - 位置不定长 *号
# 不定长定义的形式参赛会作为元组存在,接收不定长数量的参数传入
def user_info(*args):
print(f"args参数的类型是:{type(args)},内容是:{args}")
user_info(1,2,3,"小美","男孩")
# 不定长 - 关键字不定长 **号
def user_info(**kwargs):
print(f"kwargs参数的类型是:{type(kwargs)},内容是:{kwargs}")
user_info(gender="男",age=11,add="四川")
结果:
args参数的类型是:<class 'tuple'>,内容是:(1, 2, 3, '小美', '男孩')
kwargs参数的类型是:<class 'dict'>,内容是:{'gender': '男', 'age': 11, 'add': '四川'}
3. 匿名函数
(1) 函数作为参数传递:
- 在之前的函数学习中,我们一直使用的函数,都是接受数据作为参数传入:
- 数字
- 字符串
- 字典、列表、元组等
- 这是一种,计算逻辑的传递,而非数据的传递。任何逻辑都可以自行定义并作为函数传入。
# 定义一个函数,接收另一个函数作为传入参数
def test_func(compute):
result=compute(1,2) # compute是函数
print(f"compute参数的类型是:{type(compute)}")
print(f"计算结果是:{result}")
# 定义一个函数,准备作为参数传入另一个函数
def compute(x,y):
return x+y
test_func(compute)
结果:
compute参数的类型是:<class 'function'>
计算结果是:3
(2) lambda匿名函数
-
定义匿名函数(匿名函数):lambda 传入参数:函数体(一行代码)
- lambda是关键字,表示定义匿名函数
- 传入参数表示匿名函数的形式参数,如:x,y表示接收2个形式参数
- 函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
-
有名称的函数可以基于名称重复使用,无名称的匿名函数,只可临时使用一次
def test_func(compute): result=compute(1,2) print(f"计算结果是:{result}") # 通过lambda匿名函数的形式,将匿名函数作为参数传入 test_func(lambda x,y:x+y) # 函数体直接return 可以省去return
八. Python文件操作
1. 文件的编码
(1) 使用编码技术(密码本)将丰富的文本文件翻译成0和1存储在硬盘中。
(2) 编码技术,即翻译的规则,记录了如何将内容翻译成二进制,以及如何将二进制翻译回可识别内容。
(3) 计算机中有许多可用编码:
- UTF-8
- GBK
- Big5
- 等
不同的编码,将内容翻译成二进制也是不同的。
(4) 查看文件编码:可以使用Windows自带的记事本,打开文件后,就可以看见文件的编码了。
(5) UTF-8是目前全球通用的编码格式,除非有特殊需求,否则,一律以UTF-8格式进行文件编码即可。
2. 文件的读取
(1) 什么是文件:
内存中存放的数据在计算机关机后就会消失。要长久保存数据,就要使用硬盘、光盘U盘等设备。为了便于数据的的管理和检索,引入了"文件"的概念。
一篇文章、一段视频、一个可执行程序,都可以被保存为一个文件,并赋予一个文件名。操作系统以文件为单位管理磁盘中的数据。一般来说,文件可分为文本文件、视频文件、音频文件、图像文件、可执行文件等多种类别。
(2) 文件操作主要包括:打开文件、读/写文件、关闭文件。
(3) open()打开函数:在Python中,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件。
语法:open(name,mode,encoding)
-
name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)
-
mode:设置打开文件的模式(访问模式):只读、写入、追加等
- r:以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
- w:打开一个文件只用于写入。如果该文件已存在则打开文件,并从头开始编辑,原有内容会被删除。如果该文件不存在,创建新文件。
- a:打开一个文件用于追加。如果该文件已存在,新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
-
encoding:编码格式(推荐使用UTF-8)
-
f=open(‘python.txt’,‘r’,encoding=“UTF-8”)
#encoding的顺序不是第三位,所以不能用文职参数,用关键字参数直接指定
-
** 注意:此时的‘f’是open函数的文件对象,对象是Python中一种特殊的数据类型,拥有属性和方法,可以使用对象.属性或对象.方法对其进行访问。
(4)读操作相关方法
-
read()方法:文件对象.read(num)
- num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。得到的是一个字符串str。
- 在程序中,如果连续调用2次read,那么第一次read读取的结尾,就是下一次read读取的开始。
-
readlines()方法:文件对象.readlines()
- readlines可以按照行的方式把整个文件中的内容进行一次性读取,而且返回的是一个列表list,其中每一行的数据为一个元素。
- 读取文件的全部行,封装到列表中。
lines=f.readlines() print(f"lines对象的类型是:{type(lines)}") print(f"lines对象的内容是:{lines}") 结果: lines对象的类型是:<class 'list'> lines对象的内容是:['我是最棒的\n', '你也是不错的\n', '我们都是很厉害的\n', '花开花雾粉\n', '挺好的,精神状态很稳定\n', '发疯ing,不想学习ing']
-
readline()方法:文件对象.readline()
- 一次读取一行。得到的是字符串str。
content1=f.readline() print(f"第一行的内容:{content1}") content2=f.readline() print(f"第二行的内容:{content2}") content3=f.readline() print(f"第三行的内容:{content3}") 结果: 第一行的内容:我是最棒的 第二行的内容:你也是不错的 第三行的内容:我们都是很厉害的
-
for循环读取文件行:每一行是一个字符串str
# for 循环读取文件行
for line in f:
print(f"每一行的内容是:{line}")
结果:
每一行的内容是:我是最棒的
每一行的内容是:你也是不错的
每一行的内容是:我们都是很厉害的
每一行的内容是:花开花雾粉
每一行的内容是:挺好的,精神状态很稳定
每一行的内容是:发疯ing,不想学习ing
- with open() as 文件对象:通过with open 语法打开文件,可以自动关闭。
(5) 文件的关闭:文件对象.close()关闭文件对象.
- 最后通过close,关闭文件对象,也就是关闭对文件的占用;
- 如果不调用close,同时程序没有停止运行,那么这个文件一直被Python程序占用。
3. 文件的写入
(1) 步骤:
① 打开文件:f=open(“python.txt”,“w”)
② 文件写入:f.write(“hello world”)
③ 内容刷新:f.flush()
(2) 注意:
- 直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区;
- 当调用flush的时候,内容会真正写入文件;
- 这样做是为了避免频繁的操作硬盘,到知晓率下降(攒一堆,一次性写磁盘)。
- w模式,文件不存在,会创建新文件,并写上内容;
- w模式,文件存在,会清空原有内容,重新写内容;
- close()方法,带有flush() 方法的功能。
4. 文件的追加
(1) 步骤:
① 打开文件:f=open(“python.txt”,“a”)
② 文件写入:f.write(“hello world”)
③ 内容刷新:f.flush()
(2) 注意:
- a模式,文件不存在,会创建文件,并写上内容;
- a模式,文件存在,会在文件最后,追加写入文件。
- 可以使用"\n"来写出换行符。
5. 文件操作综合案例
f1=open("D:/bill.txt","r",encoding="UTF-8")
f2=open("D:/bill.txt.bak","w",encoding="UTF-8")
for line in f1:
line=line.strip() # 将字符串的回车换行符去掉
content=line.split(",") # 得到一个列表对象
if content[4]=="测试":
continue # continue进行下一次循环
f2.write(line) # 将内容写出去
# 由于前面对内容进行了strip的操作,所以要手动写出换行符
f2.write("\n")
f1.close()
f2.close()
九. Python异常、模块与包
1. 了解异常
(1) 什么是异常:当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的"异常",也就是常说的Bug。
2. 异常的捕获方法
(1) 当程序遇到了BUG,对BUG进行提醒,整个程序继续运行,这就需要使用到捕获异常。
- 捕获异常的作用在于:提前假设某处会出现异常,做好提前准备,当真的出现异常时,可以有后续手段。
(2) 基本语法:
try:
可能发生错误的代码
except:
如果出现异常执行的代码
try:
f=open("D:/abc.txt","r",encoding="UTF-8")
except:
print("出现了异常,因为文件不存在,我将open的模式改为w模式去打开")
f=open("D:/abc.txt","w",encoding="UTF-8")
(3) 捕获指定异常:
try:
print(name)
except NameError as e:
print(“name变量名称未定义错误”)
- 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。
- 一般try下方只放一行尝试执行的代码。
try:
print(name)
except NameError as e:
print("出现了变量未定义的异常")
print(e)
结果:
出现了变量未定义的异常
name 'name' is not defined
(4) 捕获多个异常:当捕获多个异常时,可以把要捕获的异常类型的名字,放到except之后,并使用元组的方式进行书写。
try:
print(1/0)
except (NameError,ZeroDivisionError):
print(‘ZeroDivision错误…’)
try:
1/0
print(name)
except(NameError,ZeroDivisionError):
print("出现了变量未定义 或者 除以0的异常错误")
(5) 捕获所有异常:
-
一种是基本捕获语法
-
另一种是:
try :
print(1/0)
except Excepion as e :
print(“出现异常了”)
# 捕获所有异常 try: 1/0 except Exception as e: # Exception是顶级的异常 print("出现异常了")
(6) 异常else:else表示的是如果没有异常要执行的代码。
try :
print(1/0)
except Excepion as e :
print(“出现异常了”)
else:
print(“我是else,是没有异常的时候执行的代码”)
try:
print("Hello")
except Exception as e:
print("出现异常了")
else:
print("好高兴,没有异常!")
结果:
Hello
好高兴,没有异常!
(7) 异常的finally:finally表示的是无论是否异常都要执行的代码,例如关闭文件。
try :
f=open(“test.txt”,“r”,encoding=“UTF-8”)
except Excepion as e :
f=open(“test.txt”,“w”,encoding=“UTF-8”)
else:
print(“我是else,是没有异常的时候执行的代码”)
finally:
f.close()
try :
f=open("D:/123.txt","r",encoding="UTF-8") 123.txt已存在
except Exception as e :
f=open("D:/123.txt","w",encoding="UTF-8")
else:
print("我是else,是没有异常的时候执行的代码")
finally:
print("我是finally,有没有异常都要执行")
f.close()
结果:
我是else,是没有异常的时候执行的代码
我是finally,有没有异常都要执行
3. 异常的传递
(1) 异常是具有传递性的,当函数func01中发生异常,并且没有捕获处理这个异常的时候,异常会传递到func02,当func02也没有捕获处理这个异常的时候,main函数会捕获这个异常,这就是异常的传递性。
- 当所有的函数都没有捕获异常的时候,程序就会报错。
4. Python模块
4.1 模块的导入
(1) Python模块:是一个Python文件,以.py结尾,模块能定义函数、类和变量,模块内也能包含可执行的代码。
(2) 模块的作用:Python中有很多各种不同的模块,每一个模块都可以帮助我们快速的实现一些功能,比如实现和时间相关的功能就可以使用time模块。可以认为一个模块就是一个工具包,每一个工具包中都有各种不同的工具供我们实现各种不同的功能。
(3) 模块的导入方式:模块在使用前需要先导入,导入的语法如下:
[from 模块名] import [模块 | 类 | 变量 | 函数 | *] [as 别名] ([]代表可选)
常用的组合形式如:
-
import 模块名
- import 模块名1,模块名2
- 模块名.功能名()
- . 用来确定层级关系
#使用import导入time模块使用sleep功能(函数) import time # 导入time内置的time模块(本质是使用time.py这个代码文件) print("你好") time.sleep(5) #执行到这条代码时会休眠5秒钟 通过 . 就可以使用模块内部的全部功能(类、函数、变量) print("我好")
-
from 模块名 import 类、变量、方法等
-
from 模块名 import 功能名
功能名()
# 使用from导入time的sleep功能(函数) from time import sleep print("hello") sleep(5) print("everyone")
- 只能使用sleep()这个功能
-
-
from 模块名 import *
-
from 模块名 import *
功能名()
-
导入模块中的所有方法
# 使用* 导入time模块的全部功能 from time import * print("nihao") sleep(5) #直接可以用功能,不需要. print("tinghao")
-
-
import 模块名 as 别名
- 给具体的模块完成改名的效果
# 使用as给特点功能加上别名 import time as t print("你好吗") t.sleep(3) print("我很好")
-
from 模块名 import 功能名 as 别名
- 给具体的功能完成改名的效果
from time import sleep as sl print("今天月色很美") sl(5) print("你也是")
4.2 自定义模块
(1) 每个Python文件都可以作为一个模块,模块的名字就是文件的名字,也就是说自定义模块必须要符合标识符命名规则。新建一个Python文件,在其中定义相关函数,最后再导入该模块,使用其中的功能。
(2) 当导入多个模块时,且模块内有同名功能,当调用这个同名功能时,调用的是后面导入的模块的功能。
# 导入不同模块的同名功能
from my_module1 import test # a+b
from my_module2 import test # a-b
test(8,3)
结果:
5
(3) 测试模块:在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息。例如,在my_moudle1.py文件中添加测试代码test(1,1)。
-
此时,无论是当前文件,还是其他已经导入了该模块的文件,在运行的时候都会自动执行"test"函数的调用。
-
只在当前文件中调用该函数,其他导入的文件内不符合该条件时,控制test函数调用。
-
if _ name _ _ == ’ _ _ main _ _':
test(1,2)
def test(a,b): print(a+b) if _ _name_ _ == '_ _main_ _': test(1,2) # __name__内置变量,当右键运行时,这个变量就会标记为main
-
(4) _ _ all _ 变量:如果一个模块文件中有‘ _ _ all_ _’变量,当使用"from xxx import*"导入时,只能导入这个列表中的元素。即,这个all变量控制了 * 的内容,决定了* 能导入哪些功能。
_ _all_ _=["testA"]
def testA(a,b):
print(a+b)
def testB(a,b):
print(a-b)
5. Python包
5.1 自定义包
(1)Python包:从物理上看,包就是一个文件夹,在该文件夹下包含了一个**__ init __.py文件**(有它才是包),该文件夹可用于包含多个模块文件;从逻辑上看,包的本质依然是模块。
(2) 包的作用:当我们的模块文件越来越多时,包可以帮助我们管理这些模块,包的作用就是包含多个模块,但包的本质依然是模块。
(3) 创建使用包:
-
pycharm中的基本步骤:
- [New] —— [Python Package] —— 输入包名 —— 新建功能模块(有联系的模块)
- 注意:新建包后,包内会自动创建’_ init _ .py’文件,这个文件控制着包的导入行为
-
导入包:
- import 包名.模块名
包名.模块名.目标
import my_package.my_module1 import my_package.my_module2 my_package.my_module1.info_print1() my_package.my_module2.info_print2() from my_package import my_module1 from my_package import my_module2 my_module1.info_print1() my_module2.info_print2() from my_package.my_module1 import info_print1 from my_package.my_module2 import info_print2 info_print1() info_print2()
-
from 包名 import*
模块名.目标
- 必须在’__ init .py’文件中添加’ _ all _=[“”],控制允许导入的模块列表’
# 通过 __all__变量控制import* from my_package import * my_module1.info_print1()
5.2 安装第三方包
(1) 什么是第三方包:
这些第三方的包,极大地丰富了Python的生态,提高了开发效率。但是由于是第三方包,所以Python没有内置,所以我们需要安装他们才可以导入使用。
(2) 安装第三方包
- 先找到python解释器所在的文件下的scripts文件,(通过命令行cd"D:/Python/Scripts")
- pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称
- 在pycharm中的解释器设置中可以查看安装的第三方包