Python语法基础
第一阶段
-
1.1 字面量
作用:字面量可以表示各种数据类型,如整数、浮点数、字符串、布尔值、列表、字典。
示例:
- 整数字面量:例如
42
,-10
,0b1010
(二进制表示的十进制数10)。 - 浮点数字面量:例如
3.14
,-0.5
,1.0e-3
(科学计数法表示的0.001)。 - 字符串字面量:例如
"Hello"
,'Python'
,"""Multiline string"""
。 - 布尔值字面量:
True
和False
。 - 列表字面量:例如
[1, 2, 3]
,['a', 'b', 'c']
。 - 字典字面量:例如
{'name': 'John', 'age': 30}
,{1: 'one', 2: 'two'}
。
- 整数字面量:例如
-
1.2 数据类型
- type语句
作用:type语句会给出执行的结果,也就是由返回值。
拓展:使用type语句查看变量中存储的数据类型信息,并且可以用变量存储。
举例:
string = "黑马程序员" a = type(string) print("string中存储的数据类型",a)
- 重点:
在python中变量是没有类型的,但是变量存储的数据它是由类型的。
例如:我们可能会说:字符串变量,但说的不是变量是字符串,而是变量中存储的数据类型是字符串。
-
1.3 数据类型的转换
-
int()语句:int(x) 将x转换为一个整数
-
float()语句:float(x) 将x转换为一个浮点数
-
str()语句:str(x) 将对象x转换为字符串
-
举例:
# 将数字类型转换为字符串 x=11 int_string=str(x) print("int_string中存储的数据类型",type(int_string),"内容:",int_string) float_string=str(13.14) print("float_string中存储的数据类型",type(float_string),"内容:",float_string) # 将字符串转换成数字 int = int("123") float = float("12.3") print(type(int),int) print(type(float),float) # 整数转换为浮点数 int_float = float(12) print("int_float中 存储数据的类型",type(int_float),int_float) # 将浮点数转换为整数 float_int = int(12.335) print("float_int中 存储的数据类型",type(float_int),float_int)
-
-
1.4 标识符的命名规则:
-
英文
-
中文
-
数字
-
下划线( _ )
-
不可使用关键字
-
这四类元素,其余任何内容都不被允许
重点:不推荐使用中文 不能以数字开头
-
1.5 运算符
- 常见的算数运算符
加、减、乘、除、整除、取余、求平方
- 赋值运算符
- 标准赋值:=
- 复合赋值:+=、-=、*=、/=、//=、%=、**=
- 1.5.1 / 的用法:
可以求出精确的浮点小数 17/4=4.25
- 1.5.2 代码实现
# 运算规则 + - * /
a = 1+1
b = 2-3
c = 2*4
e = 11/2
d = 11//2
f = 11 % 2
h = 17 / 4
j = 2**4
print("运算结果:", a)
print("运算结果:", b)
print("运算结果:", c)
print("运算结果:", e)
print("运算结果:", d)
print("运算结果:", f)
print("运算结果:", h)
print("运算结果:", j)
# 赋值运算符
num = 1 + 2 * 3
# 复合赋值运算符
num += 1
print("num += 1:", num)
num -= 1
print("num -= 1:", num)
num *= 4
print("num *= 4:", num)
num /= 2
print("num /= 2:", num)
num = 3
num %= 2
print("num %= 2:", num)
num **=2
print("num **= 2:", num)
num = 9
num //= 2
print("num //= 2:", num)
-
1.6 字符串
-
1.6.1 字符串,又称文本,是由任意数量的字符如中文、英文、各类符号、数字组成的。所以叫做字符的串。
-
1.6.2 字符串的三种定义形式和引号嵌套:
(1)单引号定义法:name = '黑马程序员',单引号定义法,可以内含双引号
(2)双引号定义法:name = "黑马程序员",双引号定义法,可以内含单引号
(3)三引号定义法:name = """黑马程序员"""
-
1.6.3 转义字符 \ 解除引号的效用
-
使用规则:\符号后加上引号
-
代码实现:
name = "'黑马程序员'" print(name) name1 = '\'黑马程序员\'' print(name1) name = '"黑马程序员"' print(name) name2 = "\"黑马程序员\"" print(name2)
-
-
1.6.4 字符串的拼接
-
操作符:+
-
字符串字面量之间的拼接
-
字符串字面量和字符串变量之间的拼接
-
代码部分
print("学IT来黑马" + "月薪过万") name = "黑马程序员" address = "建材城东路9号院" print("我是"+name+",我的地址是:"+address)
-
-
1.6.5 字符串格式化
-
操作符:%s
-
%表示:我要占位
-
s表示:将变量变成字符串放入占位的地方(数字也可以转换成字符串)
-
代码部分:
-
-
操作符:%d
-
%表示:我要占位
-
d表示:将内容转换成整数,放入占位位置
-
代码部分:
-
-
操作符:%f
-
% 表示:我要占位
-
f表示:将内容转换为浮点数
-
代码部分:
name = "传智博客" set_up_year = 2006 stock_price = 19.99 message = "我是:%s,我成立于:%d,我今天的股价是:%f" % (name, set_up_year, stock_price) print(message)
-
-
-
1.6.6 字符串格式化 - 数字精度控制
-
语法:m. n 来控制数据的宽度和精度
- m,控制宽度,要求是数字(很少使用),设置的宽度小于数字自身,不生效
- .n,控制小数点精度,要求是数字,会进行小数的四舍五入
- 正号:表示右对齐
- 负号:表示左对齐
- %5 d:表示将整数的宽度控制在5位,如数字11,被设置为5 d,会变成:[空格] [空格] [空格]11,用三个空格补足宽度
-
代码部分
num1 = 11 num2 = 11.345 print("数字11宽度限制5,结果是:%-5d" % num1) print("数字11宽度限制1,结果是:%5d" % num1) print("数字11.345宽度限制7,小数精度2,%7.2f" % num2) print("数字11.345不限制,小数精度2,结果是:%.2f" % num2)
-
-
1.6.7 字符串格式化的快速写法
-
语法:f "内容{变量}"
-
代码部分
name = "传智播客" set_up_year = 2006 stock_price = 19.99 # f: format(格式) print(f"我是{name},我成立于:{set_up_year},我今天的股票价格:{stock_price}")
-
优缺点:变量不分数据类型,也没有精度控制
-
-
1.6.8 表达式的格式化
-
表达式的定义:一条具有明确执行结果的代码语句
-
用格式化变量的方法格式表达式
-
代码部分:
print("1 * 1的结果是:%d" % (1*1)) print(f"1 * 1的结果是:{1 * 1}") print("字符串在Python中的类型是:%s" % (type('我是冯珑')))
-
-
1.6.9 字符串的上下一致对齐:\t
-
定义:一个**\t**代表的是一个制表符,在两个变量之间插入一个制表符的水平间距
-
作用:制表符常用于对齐输出,使得列与列之间对齐,从而提高可读性,在表格数据或格式化输出中经常用到制表符来创建整齐的布局
-
没有用**\t**之前:
-
使用**\t**之后:
-
代码部分:
print("----------------主菜单----------------") print("周杰伦,您好!,欢迎来到黑马银行ATM,请选择操作:") print("查询余额\t[输入1]") print("存款\t\t[输入2]") print("取款\t\t[输入3]") print("退出\t\t[输入4]")
-
结果:
-
-
-
-
1.7 实例题
-
题目:
-
代码部分
name = "传智博客" stock_price = 19.99 stock_code = "003032" stock_price_daily_growth_factor = 1.2 growth_days = 7 print(f"公司:{name},股票代码:{stock_code},当前票价:{stock_price}") print("每日增长系数是:%.1f,经过%d天的增长后,股票达到了:%.2f"%(stock_price_daily_growth_factor,growth_days,stock_price * stock_price_daily_growth_factor ** growth_days))
-
-
1.8 数据输入(input语句)
-
代码部分:
name = input("请告诉我你是谁") print("我知道了,你是:%s" % name)
-
input的默认输入类型:都是字符串类型
-
-
2.1 Python 判断语句
-
2.1.1 布尔类型和比较运算符
(1)布尔类型的字面量:
- True 表示真
- False 表示否
(2)布尔类型不仅可以自行定义,同时也可以通过计算得来,也就是使用比较运算符进行比较运算得到的布尔类型的结果
(3)比较运算符
(4)
# 布尔类型 bool_1 = True bool_2 = False print(f"bool_1的变量类型{type(bool_1)},bool_1的变量内容是{bool_1}") print(f"bool_2的变量类型{type(bool_2)},bool_2的变量内容是{bool_2}") # 比较运算符的使用 num1 = 10 == 10 print(f"10==10的结果是:{num1}") num1 = 10 num2 = 15 print(f"num1!=num2的结果是:{num1!=num2}") name1 = "itcast" name2 = "itheima" print(f"itcast == itheima 结果是{name1==name2}") # 演示 大于、小于、大于等于、小于等于 num1 = 10 num2 = 5 print(f"10>5的结果是:{num1>num2}") print(f"10<5的结果是:{num1<num2}") num1 = 10 num2 = 10 print(f"10>=10的结果是:{num1>=num2}") print(f"10<=10的结果是:{num1<=num2}")
-
2.1.2 if语句的基本格式:
(1)if 要判断的条件**:**
条件成立,要做的事情
(2)if语句的注意事项:
-
判断条件的结果一定要是布尔类型
-
不要忘记判断条件后的:冒号
-
归属于if语句的代码块,需在前方填充4个空格缩进
-
案例:
-
if 代码部分
print("欢迎来到黑马儿童游乐场,儿童免费,成人收费") age = input("请输入你的年龄:") age = int(age) if age >= 18: print(f"你已成年,游玩需要补票{10}元") print("祝你游玩愉快")
-
if else 语句
print("欢迎来到黑马儿童游乐场,儿童免费,成人收费") age = int(input("请输入你的年龄:")) if age >= 18: print("您已经成年,游玩需要补票10元") else: print("您未成年,可以免费游玩") print("祝您游玩愉快")
-
-
2.1.3 if - else if - else
-
if 条件1:
条件1满足应做的事情
-
elif 条件2:
条件2满足应做的事情
-
else:
所有条件都不满足应做的事情
-
注意事项:判断是互斥且有顺序的
- 满足1将不会理会2和3
- 满足2,将不会理会3
- 1、2、3均不满足,进入else
- else 也可以省略不写,效果等同于3个独立的if判断
-
案例
-
代码部分
real_figure = 10 if int(input("请输入第一次猜想的数字:") == real_figure): print("恭喜你猜对了") elif int(input("不对,再猜一次:") == real_figure): print("恭喜你猜对了") elif int(input("不对,再猜最后一次:") == real_figure): print("恭喜你猜对了") else: print(f"Sorry,全部猜错啦,我想的是:{real_figure}")
-
-
2.1.4 if语句的嵌套
-
定义:判断语句嵌套指的是在一个判断语句的代码块中嵌套另一个判断语句。判断语句(也称为条件语句)用于根据给定的条件执行不同的代码路径。
-
案例1:
-
代码部分:
age = int(input("请输入您的年龄:")) if age >= 18: if age <= 30: if int(input("请输入你的入职时间:")) > 2: print("小于30岁的成年人且入职时间超过2年,满足条件,可以领取") else: print("入职时间太短了,不能领取礼品呦!") elif int(input("请输入你的级别:")) > 3: print("级别大于3,符合条件,可以领取") else: print("你的年龄过大,或者级别小于3,不可领取") else: print("Sorry,未成年不能领取礼物。")
-
案例2:
-
代码部分:
import random num = random.randint(1, 10) print(f"提前告诉你正确答案:{num}") guess_num1 = int(input("请输入第一次猜测的数字:")) if guess_num1 == num: print("你真聪明,第一次就猜对了!") else: if guess_num1 > num: print("您猜的大了") else: print("您猜的小了") guess_num2 = int(input("请输入第二次猜测的数字:")) if guess_num2 == num: print("你真棒,第二次猜对了") else: if guess_num2 > num: print("您猜大了") else: print("您猜小了") guess_num3 = int(input("请输入第三次猜测的数字:")) if guess_num3 == num: print("还不错,总算是猜对了") else: print("三次机会用完了,没有猜中") print(f"正确答案是:{num}")
-
-
-
3.1 Python循环语句
-
3.1.1 while循环语句:
1.语法格式:
while 条件:
- 条件满足时,做的事情1
- 条件满足时,做的事情2
2.注意事项:
- 条件需提供布尔类型结果,True继续,False停止
- 空格缩进不能忘
- 请规划好循环终止条件,否则将无限循环
3.代码部分:
i = 0 while i < 100: print("小美,我喜欢你") i += 1
-
3.1.2 while嵌套循环
1.语法格式:
while 条件1:
条件1满足时,做的事情1
条件2满足时,做的事情2
.......................................
while 条件2:
条件2满足时,做的事情1
条件2满足时,做的事情2
......................................
2.案例1
题目:
i = 1 while i <= 100: print(f"今天是第{i}天,准备表白....") j = 1 while j <= 10: print(f"送给小美第{j}朵花") j += 1 i += 1 print(f"坚持到第{i-1}天,表白成功")
3.案例2
-
题目:九九乘法口诀
-
修正前的代码:
i = 1 while i <= 9: j = 1 while j <= i: print(f"{j}*{i}={i*j}\t", end='',) j += 1 print() i += 1 print("以上就是九九乘法口诀")
-
修正后的代码
i = 1 while i <= 9: j = 1 while j <= i: print(f"{j}*{i}={i*j}\t", end='') #\t 对齐符 表中进行对齐 j += 1 i += 1 print() print("以上就是九九乘法口诀")
4.注意事项:
- 注意条件的控制,避免无限循环
- 多层嵌套,主要空格缩进来确定层次关系
- 循环条件的控制,层次越多越复杂,需要细心+耐心
-
-
3.1.3 for 循环(遍历循环)
-
语法格式:
for 临时变量 in 待处理数据集 (序列类型)
-
代码格式:
name = "itheima" for x in name:# x代表的是数值 而不是数值的序号 print(x, " ", end='')
-
-
3.1.4 rang语句:可以获得一个简单的数字序列。
-
语法格式:
- range(num) 数字序列包含{0,1,2,... ,num-1}
- range(num1,num2) 获得一个从num1开始,到num2-1结束的数字序列
- range(num1,num2,step) 获得一个从num1到num2-1结束的数字序列,数字之间的
步长,以step为准。
-
代码格式:
for x in range(9): print(x, " ", end='') for x in range(2, 10): print(x, " ", end='') for x in range(1, 20, 3): print(x, " ", end='')
-
-
3.1.5 for循环的嵌套
-
语法格式:
for 临时变量 in 待处理数据集(序列):
循环满足条件应做的事情1
循环满足条件应做的事情2
.......................................
for 临时变量 in 待处理数据集(序列):
循环满足条件应做的事情1
循环满足条件应做的事情2
.......................................
-
注意事项:
- 注意缩进
-
案例1:表白小美
i = 1 for i in range(1, 101): print(f"今天是向小美表白的第{i}天,坚持。") for j in range(1, 11): print(f"送给小美的第{j}朵玫瑰花。") print(f"小美,我喜欢你") print(f"第{i}天表白成功")
-
案例2:九九乘法口诀(for循环版)
for i in range(1,10): for j in range(1,i+1): print(f"{j}*{i}={j*i}\t", end='') print() print("以上就是九九乘法口诀")
-
-
-
3.1.6 break和continue的两个关键字
-
定义:
- continue 中断所在循环的当次执行,直接进入下一次
- break 直接结束所在循环
-
代码展示:
for i in range(1,6): print("语句1") continue print("语句2") for j in range(1,10) print("语句2") break print("语句3")
-
注意事项:
- continue和break,在for和while循环中作用一致
- 在嵌套循环中,只能作用在所在的循环中,无法
无法对上层循环起作用。
-
案例1:
-
代码部分:
money = 10000 for i in range(1, 21): import random num = random.randint(1, 11) if num < 5: print(f"员工{i},绩效分{num},低于5,不发工资,下一位") continue if money >= 1000: money = money - 1000 print(f"向员工{i}发放工资1000元,账户余额还剩余{money}元") else: print("工资发完了,下个月领取吧!") break
-
-
4.1 Python函数
-
4.1.1 函数介绍
-
定义:是组织好的,可重复使用的,用来实现特定功能的代码段
-
语法:
def 函数名(传入参数): 函数体 return 返回值
-
函数的调用:函数名(参数)
-
注意事项:
(1)参数如不需要,可以省略
(2)返回值如不需要,可以省略
(3)函数必须先定义后使用
-
-
4.1.2 函数的传入参数
-
功能:在函数进行计算的时候,接受外部(调用时)提供的数据
-
传参定义的语法:
def 函数名(传入参数) 函数体 return 返回值
-
注意事项:传入参数的数量是不受限制的
-
-
4.1.3 None类型
-
定义:函数返回的None,就表示,这个函数没有返回什么有意义的内容,也就是返回了空的意思。
-
函数如何返回None:
- 不适用return语句即返回None
- 主动return None
-
使用场景:
(1)在if判断语句中,None 等同于 false
(2)一般用于在函数中主动返回None,配合if判断做相关处理
例如:
def check_age(age) if age > 18: return "SUCCESS" return None result = check_age(5) if not result print("未成年,不可进入")
(3)定义变量,但暂时不需要变量有具体值,可以用None来代替。
例:name = None
-
代码演示:
def say_hello(): print("Hello...") # 使用变量接收say_hello函数的返回值 result = say_hello() # 打印返回值 print(f"无返回值函数,返回的内容是:{result}") # 打印返回值的类型 print(f"无返回值函数,返回的内容类型是:{type(result)}") # None可以主动使用return返回,效果等同于不写return语句:(即None) def say_hello(): print("Hello...") return None (或者None) # 有返回值的 result = say_hello print(result) print(type(result))
-
-
4.1.4 函数的说明文档
-
作用:对函数进行说明解释,帮助更好理解函数的功能
-
定义语法:
def func(x, y): """ 函数说明 :param x: 参数x的说明 :param y: 参数y的说明 :return: 返回值的说明 """ 函数体 return 返回值
- :param 用于解释参数
- :return 用于解释返回值
-
代码演示:
def func(x, y) result = x + y print(f"两个数相加的结果是:{result}") return result func(2,4)def func(x, y): """ func函数可以接收2个参数,进行2数相加的功能 :param x: 形参x表示相加的其中一个数字 :param y: 形参y表示相加的另一个数字 :return: 返回值是2数相加的结果 """ result = x + y print(f"两个数相加的结果是:{result}") return result func(2,4)
-
-
4.1.5 函数的嵌套
-
定义:函数的嵌套调用指的是一个函数里面又调用了另一个函数
-
执行流程:
函数A中执行到调用函数B的语句,会将函数B全部执行完成后,继续执行函数A的剩余内容。
-
-
4.1.6 变量在函数中的作用域
-
局部变量
- 定义:在函数体内部的变量,即只在函数体内部生效
- 作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量
-
全局变量
- 定义:在函数体内、外都能生效的变量
-
global关键字
-
作用:使用global关键字,可以在函数内部声明变量(局部变量)为全局变量
-
代码部分
num = 100 def testA(): print(num) def testB(): #global 关键字声明函数numB中的变量num为全局变量 global num num = 200 print(num) testA() testB() # num值被修改 print(f"全局变量num = {num}")
-
-
4.1.7 综合案例
-
题目:
-
代码部分
total = 5000000 name = None name = input("请输入您的姓名:") def check(flag): if flag: print("----------------查询余额----------------") print(f"{name},您的余额剩余{total}元") def deposit(a): # 要想继续使用并且改变全局变量total的值,global要在定义函数的第一句使用 # 在后边使用global编译器会报错 # total在下面再定义,就是局部变量,故要用global关键字 global total total = total + a print("----------------存款----------------") print(f"{name},您好,您存款{a}元成功") # print(f"周杰伦,您好,您的余额剩余:{total}元") check(False) def takeout(a): # 要想继续使用并且改变全局变量total的值,global要在定义函数的第一句使用 # 在后边使用global编译器会报错 # total在下面再定义,就是局部变量,故要用global关键字 global total total = total - a print("----------------取款----------------") print(f"{name},您好,您取款{a}元成功") # print(f"周杰伦,您好,你的余额剩余:{total}元") check(False) def main(): print("----------------主菜单----------------") print(f"{name},您好!,欢迎来到黑马银行ATM,请选择操作:") print("查询余额\t[输入1]") print("存款\t\t[输入2]") print("取款\t\t[输入3]") print("退出\t\t[输入4]") flag = True while flag: main() num = int(input("请输入您的选择:")) if num == 1: check(True) continue elif num == 2: x = int(input("您要存入的金额:")) deposit(x) continue elif num == 3: x = int(input("您要取出的金额:")) takeout(x) continue elif num == 4: flag = False break
-
-
-
5.1 Python 数据容器
-
5.1.1 Python中的数据容器:
- 定义:
一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素
每一个元素,可以是任意类型的数据,如:字符串、数字、布尔等
-
类型:
按是否支持重复元素、是否可以修改、是否有序等分为5类,分别是列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)
-
5.1.2 列表list
-
定义语法:[元素1,元素2,元素3......]
-
元素:数据容器中的每一份数据,都称之为元素
-
类型限制:元素的数据类型没有任何限制,甚至元素可以是列表,这样就定义了嵌套列表
-
列表的下标索引:
(1)列表的每一个元素,都有编号称之为下标索引
(2)从前往后的方向,编号从0开始递增
(3)从后往前的方向,编号从-1开始递减(如下图)
-
通过下标索引取出对应位置的元素
# 取出一般列表中的元素 my_list = ['itheima', 666, True] print(my_list) print(my_list[0]) print(my_list[-2]) print(my_list[2]) # 取出嵌套列表中的元素 com_list = [[1, 2, 3], [4, 5, 6]] print(com_list) print(com_list[0]) print(com_list[0][2])
-
下标索引的注意事项:
- 要注意下标索引的取值范围,超出范围无法取出元素 ,并且会报错
-
-
5.1.3 列表list的常用操作(方法)
-
查找某元素的下标 index
-
功能:查找指定元素在列表的下标,如果找不到,报错ValueError
-
语法:列表.index(元素)
-
代码部分:
my_list = ["itcast", "itheima", "python"] p = my_list.index("python") print(f"该元素在my_list中的位置:{p}")
-
-
修改特定位置(索引)的元素值:
-
语法:列表[下标] = 值
-
代码部分:
# 正向下标 my_list = [1, 2, 3] my_list[1] = 5 print(my_list) # 反向下标 my_list = [4, 5, 6] my_list[-3] = 8 print(my_list)
-
-
插入元素:insert
-
语法:列表.insert(下标,元素),在指定的下标位置,插入指定的元素
-
代码部分:
my_list = ["itheima", "itcast", "python"] my_list.insert(1, "best") print(my_list)
-
-
追加一个元素:append
-
语法:列表.append(元素),将指定元素,追加到列表的尾部
-
代码部分:
my_list = ["itheima", "itcast", "python"] my_list.append("黑马程序员") print(f"列表在追加元素后的结果:{my_list}")
-
-
追加一批元素:extend
-
语法:列表.extend(其他数据容器),将其他容器的内容取出,依次追加到列表尾部
-
代码部分:
my_list = ["itcast", "itheima", "python", "黑马程序员"] add_list = [1, 2, 3] my_list.extend(add_list) print(f"追加一批元素后的结果:{my_list}")
-
-
元素删除:pop
-
语法1:del 列表[下标]
-
语法2:列表.pop(下标) 可以得到返回值并移除该元素
-
代码部分
my_list = ["itcast", "itheima", "python", "黑马程序员"] # del 列表[下标] del my_list[3] print(my_list) # 列表.pop(下标) element = my_list.pop(0) print(f"通过pop方法删除后列表中的元素为:{my_list}")
-
-
删除某元素在列表中的第一个匹配项:remove
-
语法:列表.remove(元素)
-
代码部分:
# 只删除某元素在列表中的一个匹配项 my_list = [1, 2, 3, 2, 3] my_list.remove(2) print(f"移除某一个元素后的列表为:{my_list}")
-
-
清空列表内容:clear
-
语法:列表.clear()
-
代码部分:
my_list = [1, 2, 3] my_list.clear() # 清空列表内的所有内容 print(f"列表被清空了,结果是:{my_list}")
-
统计列表内某元素的数量:count
-
语法:列表.count(元素)
-
代码部分:
my_list = [1, 1, 1, 2, 3] num = my_list.count(1) print(num)
-
-
统计列表内,有多少元素:len
* 语法:len(列表)
* 代码部分: ```python my_list = {"itcast", "itheima", "itcast", "itheima", "python"} num = len(my_list) print(f"列表元素的数量总共有:{num}个") ```
11. 列表的特点:
* 可以容纳多个元素(上限为2**63 - 1) * 可以容纳不同类型的元素(混装) * 数据是有序存储的(有下标序号) * 允许重复数据存在 * 可以修改(增加或删除元素)
-
案例:
-
代码部分:
-
a_list = [21, 25, 21, 23, 22, 20] # 1.追加一个数字31 a_list.append(31) # 2.追加一个新列表[29,33,30] add_list = [29, 33, 30] a_list.extend(add_list) # 3.取出第一个元素 print(a_list[0]) # 4.取出最后一个元素 l = len(a_list) print(a_list[l-1]) # 或者为: l1 = a_list[-1] print(l1) # 5.查找元素31,在列表中的下标的位置 p = a_list.index(31) print(f"元素31的下标位置为{p}") print(a_list)
-
-
-
-
5.1.4 (list)列表的遍历
-
遍历的定义:
将容器内的元素依次取出,并处理,称之为遍历操作
-
掌握使用while循环,遍历列表的元素
def list_while_func(): my_list = ["传智教育", "黑马程序员", "Python"] index = 0 while index < len(my_list): element = my_list[index] print(f"列表的元素:{element}") index += 1 list_while_func()
-
掌握使用for循环,遍历列表的元素
def list_for_func(): my_list = [1, 2, 3, 4, 5] for element in my_list: print(f"列表中的元素:{element}") list_for_func()
-
-
案例:
-
题目:
-
-
代码部分:
my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] else_list = [] index = 0 while index < len(my_list): element = my_list[index] if element % 2 == 0: else_list.append(element) index += 1 print(f"通过while循环,从列表:{my_list}中取出偶数,组成新列表:{else_list}") my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] list1 = [] for element in my_list: if element % 2 == 0: list1.append(element) print(f"通过for循环,从列表:{my_list}中取出偶数,组成新列表:{list1}")
-
-
5.1.5 元组
-
元组的定义:同列表一样,都是可以封装多个、不同类型的元素在内
-
元组的特点:
-
元组一旦定义完成,就不可篡改
-
元组中的列表(list)可以改变
-
-
元组的语法:
# 定义元组字面量 (元素,元素,......,元素) # 定义元组变量 变量名称 = (元素,元素,......,元素) t1 = (1,"Hello",True) # 若元组只有一个数据,这个数据后面要添加逗号 t4 = ('Hello',) print(f"t4的类型:{type(t4)}") # 定义空元组 变量名称 = () #方式1 变量名称 = tuple() #方式2 t2 = () t3 = tuple() # 元组的嵌套 t5 = ((1,2,3),(4,5,6)) print(f"t5的类型:{type(t5)}") print(t5[1][2])
-
元组的相关操作:
-
index()、count()、len()
-
代码部分:
t6 = ("传智教育", "黑马程序员", "python") p = t6.index("黑马程序员") print(f"在元组t6中查找黑马程序员,的下标是{p}") t7 = ("传智教育", "黑马程序员", "黑马程序员", "黑马程序员", "Python") num = t7.count("黑马程序员") print(f"在元组t7中黑马程序员的个数{num}个") t8 = ("传智教育", "黑马程序员", "黑马程序员", "黑马程序员", "Python") num = len(t8) print(f"t8元组中的元素有:{num}个")
-
-
元组的遍历:
-
while:
t = ("冯珑", "冯书功", "马玲花", "冯淼", "竺柯") def while_tuple(): index = 0 while index < len(t): t1 = t[index] print(f"元组t中的元素为:{t1}") index += 1
-
for
t = ("冯珑", "冯书功", "马玲花", "冯淼", "竺柯") def for_tuple(): for x in t: print(f"元组t中的元素为:{x}") for_tuple()
-
题目:
-
代码部分:
t = ("周杰伦", 11, ["football", "music"]) p = t.index(11) print(f"年龄所在的位置:{p}") print(f"查询学生的姓名:{t[0]}") # del t[2][0] print(t[2]) t[2].append("coding") print(t[2])
-
-
-
-
5.1.6 字符串(字符的容器)
-
字符串的下标(索引)
(1)从前向后,下标从0开始
(2)从后向前,下标从-1开始
-
特点:
-
字符串是只读的容器,不支持修改
-
只可以存储字符串,允许重复字符串存在
-
-
字符串的常用操作:
-
查找特定字符串的下标索引值: index
-
语法:字符串.index(字符串)
my_str = "itheima and itcast" value = my_str.index("and") print(f"在字符串{my_str}中查找and,其起始下标是:{value}")
-
字符串的替换: replace
-
语法:字符串.replace(字符串1,字符串2)
-
功能:将字符内的全部:字符串1,替换为字符串2
-
注意:不是修改字符串本事,而是得到了一个新字符串哦
-
代码部分:
my_str = "itheima and itcast" new_my_str = my_str.replace("it", "程序") print(new_my_str) # my_str并没有改变 print(my_str)
-
字符串的分割:split
-
语法:字符串.split(分隔符字符串)
-
功能:按照指定的分隔符字符串,将字符串分为多个字符串,并存入列表对象中
-
注意:字符串本身不变,而是得到一个列表对象
-
代码部分:
my_str = "hellohhpythonhhitheimahhitcast" my_str_list = my_str.split("hh") print(my_str_list,type(my_str_list))
-
字符串的规整操作(去除前后空格和换行符)strip
-
语法:字符串.strip()
-
演示:
my_str = " itheima an itcast " print(my_str.strip())
-
字符串的规整操作(去除前后指定的字符串)
-
语法:字符串.strip("12")
-
演示:
my_str = "12itheima an itcast21" # 这里的”12“ 不是字符串12 而是字符1和字符2 print(my_str.strip("12"))
-
统计字符串中某字符串的出现次数 count
-
语法:字符串.count("字符串")
-
统计字符串的长度:len
- 语法:len("字符串") (有返回值)
-
实例:
-
题目:
-
代码部分:
my_str = "itheima itcast boxuegu" num = my_str.count("it") print(f"字符串{my_str}中有:{num}个it字符") new_str = my_str.replace(" ", "|") print(new_str) new_str_list = new_str.split("|") print(new_str_list)
-
-
-
-
-
5.1.7 数据容器(序列)的切片
-
序列:
-
定义:内容连续、有序,可使用下标索引的一类数据容器
-
列表、元组、字符串,均可以视为序列
-
-
切片:从一个序列中,取出一个子序列
-
语法:序列[起始下标:结束下标:步长]
-
下标真正结束的位置是:结束下标 - 1
-
步长表示,依次取元素的间隔
- 步长1表示,一个个取元素
- 步长2表示,每次跳过1个元素取
- 步长N表示,每次跳过N-1个元素取
- 步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)
-
注意:切片操作不会影响序列本身,而是得到一个新的序列
- 代码部分:
# 对list列表进行切片,从1开始,4结束,步长1 my_list = [0, 1, 2, 3, 4, 5, 6] new_my_list = my_list[1:4:1] print(f"结果1:{new_my_list}") # 对tuple进行切片,从头开始,到最后结束,步长1 my_tuple = (0, 1, 2, 3, 4, 5, 6) # 从头到尾的切片,起始下标和结束下标都可以不写,步长为1也不写 new_my_tuple2 = my_tuple[:] # 或 new_my_tuple = my_tuple[0::1] print(f"结果2:{new_my_tuple}") # 对str进行切片,从头开始,到最后结束,步长2 my_str = "itheimaitcastpython" new_my_str = my_str[::2] print(f"结果3:{new_my_str}") # 对str进行切片,从头开始,到最后结束,步长为-1 my_str1 = "冯珑冯书功冯淼马玲花" new_str_str1 = my_str1[-1::-1] print(f"结果4:{new_str_str1}") # 对列表进行切片,从3开始,到1结束,步长为-1 my_list1 = [5, 9, 3, 6, 4, 8, 1] L = len(my_list1) new_my_list1 = my_list1[3:1:-1] new_my_list2 = my_list1[3-L:1-L:-1] print(f"结果5:{new_my_list2}") # 对元组进行切片,从开开始,到尾结束,步长-2 my_tuple1 = (2, 2, 1, 0, 1, 1, 3) new_my_tuple1 = my_tuple1[-1::-2] print(f"结果6:{new_my_tuple1}")
-
案例:
-
题目:
-
代码部分:
my_str = "万过薪月,员序程马黑来,nohtyp学" # 方法1:直接切片 result1 = my_str[9:4:-1] print(f"结果1是: {result1}") # 方法2:把字符串换成列表 result2 = my_str.split(",")[1].replace("来", " ")[::-1] print(f"结果2是:{result2}")
-
-
-
-
5.1.8 set(集合)
-
集合定义:
-
基本语法:
# 定义集合字面量 {元素,元素,......,元素} # 定义集合变量 变量名称 = {元素,元素,......,元素} # 定义空集合 变量名称 = set()
-
特点:
- 集合是无序的、不能重复的,所以集合不支持:下标索引访问
- 集合和列表一样,是允许修改的
-
-
集合的操作:
-
添加新元素:add
-
语法:集合.add(元素)。将指定元素,添加到集合内
-
结果:集合本身被修改,添加了新元素
-
代码:
my_set = {"Hello,World!"} my_set.add("itheima") print(f"my_set添加元素后的结果:{my_set}")
-
-
移除元素:remove
-
语法:集合.remove(元素),将指定元素,从集合内移除
-
结果:集合本身被修改,移除了元素
-
代码:
my_set = {"黑马程序员", "传智教育", "itheima","黑马程序员", "传智教育", "itheima"} my_set.remove("itheima") print(f"my_set被移除后的结果:{my_set}")
-
-
从集合中随机取出元素:pop
-
语法:集合.pop(元素),功能:从集合中随机取出一个元素
-
结果:会得到一个元素的结果,同时集合本身被修改,元素被移除
-
代码:
my_set = {"黑马程序员", "传智教育", "itheima","黑马程序员", "传智教育", "itheima"} element = my_set.pop() print(f"随机取出一个元素的结果:{element}") print(my_set)
-
-
清空集合:clear
- 语法:集合.clear()
-
取2个集合的差集:difference
-
语法:集合1.difference(集合2),功能:取出集合1和集合2的差集(集合1有而集合2没有的)
-
结果:得到一个新集合,集合1和集合2不变
-
代码
set1 = {1, 2, 3} set2 = {1, 5, 6} set3 = set1.difference(set2) print(f"取差集后的结果:{set3}")
-
-
消除2个集合的差集:difference_update
-
语法:集合1.difference_update(集合2)
-
功能:对比集合1和集合2,在集合1内,删除和集合2相同的元素。
-
结果:集合1被修改,集合2不变,并且没有返回值
-
代码:
set1 = {1, 2, 3} set2 = {1, 5, 6} set1.difference_update(set2) print(f"取差集后的结果:{set1}") print(set2)
-
-
2个集合合并:union
-
语法:集合1.union(集合2)
-
功能:将集合1和集合2组合成新集合,集合1和集合2不变
-
代码:
set1 = {1, 2, 3} set2 = {1, 5, 6} set3 = set1.union(set2) print(f"取并集后的结果:{set3}")
-
-
统计集合的元素数量:len
- 语法:变量 = len(set1)
-
集合的遍历:for循环
-
代码演示:
set1 = {1, 2, 3, 4, 5} for element in set1: print(f"集合的元素有:{element}")
-
-
-
-
5.1.9 dict(字典、映射)
-
字典的定义:
-
使用符号为{},不过存储的元素是一个个的:键值对
-
语法:
# 定义字典字面量 {key:value, key:value, ......, key:value} # 定义字典变量 my_dict = {key:value, key:value, ......, key:value} # 定义空字典 my_dict = {} my_dict = dict()
-
代码:
my_dict = {"冯珑": 87, "数据库": 70, "计算机组成原理": 75} my_dict1 = dict() my_dict2 = {} #在集合中只有一种定义空集合的方法,{}被字典dict占用 print(f"my_dict的内容:{my_dict}\nmy_dict的类型:{type(my_dict)}") print(f"my_dict1的内容:{my_dict1}\nmy_dict1的类型:{type(my_dict1)}") print(f"my_dict2的内容:{my_dict2}\nmy_dict2的类型:{type(my_dict2)}")
-
-
字典数据的获取
(1) 字典可以通过Key值来取得对应的Value(不能通过下标索引来寻找)
-
代码:
stu_score = {"王力宏": 99, "周杰轮": 88, "林俊节": 77} print(stu_score["王力宏"]) print(stu_score["周杰轮"]) print(stu_score["林俊节"])
(2) 字典的注意事项:
-
键值对的Key和Value可以是任意类型(Key不可为字典)
-
字典内Key不允许重复(一个key只允许对应一个value),重复添加等于覆盖原有数据
-
字典不可用下标索引,而是通过Key检索Value
(3) 字典的嵌套:
- 定义:{Key: {Key: Value}}
- 题目:
-
代码部分:
star_score = {"王力宏": {"语文": 77, "数学": 66, "英语": 33}, "周杰伦": {"语文": 88, "数学": 86, "英语": 55}, "林俊杰": {"语文": 99, "数学": 96, "英语": 66} } score = star_score["王力宏"]["语文"] print(f"王力宏的语文成绩:{score}") print(star_score["林俊杰"]["英语"])
-
-
字典的常用操作:
-
新增元素:
语法:字典[Key] = Value,结果:字典被修改,新增元素
-
更新元素:
语法:字典[Key] = Value,结果:字典被修改,元素被更新
-
两者的代码:
# 新增元素 my_dict["张信哲"] = 66 print(f"字典经过新增元素后,结果:{my_dict}") # 更新元素 my_dict["周杰轮"] = 89 print(f"字典经过更新后,结果是:{my_dict}")
-
删除元素:pop
语法:字典.pop(Key),结果:获得指定Key的Value,同时字典被修改,指定Key的数据被删除
代码:
my_dict = {"周杰轮": 99, "林俊杰": 88, "张学友": 77} score = my_dict.pop("周杰轮") print(f"字典删除元素的结果是:{my_dict},周杰轮的考试分数是:{score}")
-
清空元素:clear
语法:字典.clear()
-
获取全部Key的操作:keys
语法:字典.keys(),结果:得到字典中的全部Key
代码:
my_dict = {"周杰轮": 99, "林俊杰": 88, "张学友": 77} keys = my_dict.keys() print(f"字典的全部Keys是:{keys}")
-
遍历字典:for循环
代码:
# 方法1:通过keys来遍历 my_dict = {"周杰轮": 99, "林俊杰": 88, "张学友": 77} keys = my_dict.keys() for key in keys: print(f"字典的key是:{key}") print(f"字典的Value是:{my_dict[key]}") # 方法2:直接对字典进行for循环,每一次循环都是直接得到key for key in my_dict: print(f"字典的key是:{key}") print(f"字典的value是:{my_dict[key]}")
-
统计字典内的元素数量:len()
语法:变量 = len(字典)
-
案例:
-
题目:
-
代码:
employee_dict = {"王力鸿": {"部门": "科技部", "工资": 3000, "级别": 1}, "周杰轮": {"部门": "市场部", "工资": 5000, "级别": 2}, "林俊节": {"部门": "市场部", "工资": 7000, "级别": 3}, "张学油": {"部门": "科技部", "工资": 4000, "级别": 1}, "刘德滑": {"部门": "市场部", "工资": 6000, "级别": 2} } print(f"全体员工当前信息如下,\n{employee_dict}") for key in employee_dict: if employee_dict[key]["级别"] == 1: employee_dict[key]["级别"] += 1 employee_dict[key]["工资"] += 1000 print(f"全体员工级别为1的员工完成升值加薪操作,操作后,\n{employee_dict}")
-
5.2.0 总结
- 数据容器特点对比
-
适用场景
-
5.2.1 数据容器的通用操作
-
遍历
(1)5类数据容器都支持for循环遍历
(2)列表、元组、字符串支持while循环,集合、字典不支持(无下标索引)
-
len 容器:len(容器)
-
max容器:max(容器)
-
min容器:min(容器)
-
容器转换操作:
my_list = [1, 2, 3, 4, 5] my_tuple = (1, 2, 3, 4, 5) my_str = "abcdefg" my_set = {1, 2, 3, 4, 5} my_dict = {"key1": 1, "key2": 2, "key3": 3, "key4": 4, "key5": 5} # 容器转列表 print(f"列表转列表的结果是:{list(my_list)}") print(f"元组转列表的结果是:{list(my_tuple)}") print(f"字符串转列表的结果是:{list(my_str)}") print(f"集合转列表的结果是:{list(my_set)}") print(f"字典转列表的结果是:{list(my_dict)}") # 容器转元组 print(f"列表转元组的结果是:{tuple(my_list)}") print(f"元组转元组的结果是:{tuple(my_tuple)}") print(f"字符串转元组的结果是:{tuple(my_str)}") print(f"集合转元组的结果是:{tuple(my_set)}") print(f"字典转元组的结果是:{tuple(my_dict)}") # 容器转字符串 # 输出时会把双引号自动去掉 print(f"列表转字符串的结果是:{str(my_list)}") print(f"元组转字符串的结果是:{str(my_tuple)}") print(f"字符串转字符串的结果是:{str(my_str)}") print(f"集合转字符串的结果是:{str(my_set)}") # 字典转字符串时 会保留value print(f"字典转字符串的结果是:{str(my_dict)}") # 容器转集合 print(f"列表转集合的结果是:{set(my_list)}") print(f"元组转集合的结果是:{set(my_tuple)}") print(f"字符串转集合的结果是:{set(my_str)}") print(f"集合转集合的结果是:{set(my_set)}") print(f"字典转集合的结果是:{set(my_dict)}") # 容器转字典 没有办法转换 不会凭空产生一个value值 # print(f"列表转字典的结果是:{dict(my_list)}") # print(f"元组转字典的结果是:{dict(my_tuple)}") # print(f"列表转字典的结果是:{dict(my_str)}") # print(f"列表转字典的结果是:{dict(my_set)}") # print(f"列表转字典的结果是:{dict(my_dict)}")
-
容器通用排序功能:
-
语法:newlist = sorted(容器, reverse = True) (有返回值,且返回值的类型为列表)
-
注意事项:
- 默认第二个参数是False,从小到大排序 sorted(容器)
- 若第二个参数传递为True,进行从大到小的排序 sorted(容器, reverse=True)
-
代码
my_list = [1, 2, 3, 4, 5] my_tuple = (1, 2, 3, 4, 5) my_str = "abcdefg" my_set = {1, 2, 3, 4, 5} my_dict = {"key1": 1, "key2": 2, "key3": 3, "key4": 4, "key5": 5} my_list1 = sorted(my_list, reverse=True) print(f"排序后的结果是:{my_list1}") print(f"排序后的结果是:{sorted(my_tuple, reverse=True)}") print(f"排序后的结果是:{sorted(my_str)}") print(f"排序后的结果是:{sorted(my_set)}") print(f"排序后的结果是:{sorted(my_dict)}")
-
-
-
-
-
-
6.1 函数的进阶
-
6.1.1 函数的多返回值
-
使用多个变量,接收多个返回值
def test_return(): return 1, "Helllo", True x, y, z = test_return() print(x) print(y) print(z)
-
-
6.1.2 函数的多种传参方式
-
位置参数
-
定义:位置参数(Positional Arguments)是指根据参数在参数列表中的位置进行传递和匹配的参数。
-
调用实例:user_info(name, age,gender)
-
关键字参数
-
定义:函数调用时通过“键=值”形式传递参数
-
调用实例:user_info(name="小明", age= 20, gender="男")
-
位置参数和关键字参数混用:user_info("小明", age=20, gender="男")
- 注意:混用时,位置参数必须放在关键字参数的前面,包括函数的定义和调用,但关键字参数之间不存在先后顺序
-
代码
def user_info(name, age, gender): print(f"姓名是:{name}, 年龄是:{age},性别是:{gender}") # 按位置参数进行传参 user_info(name="小王", age=11, gender="女") # 按关键字参数进行传参 user_info(age=10, gender="女", name="潇潇") # 混用时 user_info("范冰冰", gender="女", age=23)
-
不定长参数
-
定义:也叫可变参数,用于不确定调用的时候会传递多少个参数(不传参也可以)的场景
-
类型:位置传递和关键字传递
-
位置传递 *号
def user_info(*args): print(args) user_info("TOM") user_info("TOM", 18)
-
注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),ags是元组类型,这就是位置传递
-
关键字传递 **号
def user_info1(**kwargs): print(kwargs) user_info1(gender="中") user_info1(name="TOM", age=18, id=180)
-
注意:参数是**"键=值"形式的情况下,所有的"键=值"都会被kwargs接受,同时会根据"键=值"组成字典**
-
-
缺省参数
-
定义:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注:所有位置参数要出现在缺省参数之前,包括函数的定义和调用)
-
代码
# 默认值必须在最后 def user_info(name, age, gender="男"): print(f"姓名是:{name}, 年龄是:{age},性别是:{gender}") user_info("小天",23)
-
-
6.1.3 匿名函数
-
函数作为参数传递
-
重点:函数作为参数传递,是计算逻辑的传递,而非数据的传递。(计算的数据是确定的,函数不确定)
-
代码:
def test_func(compute): # compute是函数 result = compute(2, 3) print(result) print(type(compute)) def add(x, y): return x*y test_func(add)
-
lambda 匿名函数
-
定义:lambda关键字,可以定义匿名函数(无名称)有名称的函数,可以基于名称重复使用,无名称的匿名函数,只可临时使用一次。
-
语法:lambda 传入参数:函数体(一行代码)
- 函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
- 在调用父函数时,lambda匿名函数
-
代码部分
def test_func(compute): result = compute(1, 2) print(f"结果是:{result}") # 应用比较简洁 test_func(lambda x, y: x + y)
-
-
-
-
7.1 python文件操作
-
7.1.1 文件编码
- 编码定义:编码是一种规则集合,记录了内容和二进制间进行相互转换的逻辑
- 编码格式:UTF-8是目前全球通用的编码格式,除有特殊需求,否则,一律以UTF-8格式进行文件编码
-
7.1.2 文件的操作步骤
-
打开文件
-
open()打开函数
- 语法:open(name, mode, encoding)
- name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)
- mode:设置打开文件的模式:只读、写入、追加等
- encoding:编码格式(推荐使用UTF-8)
-
-
读写文件
-
read()方法:
- 语法:文件对象.read(num)
- 注:num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就读取文件中所有的数据。
- 读出数据的数据类型是字符串
-
readlines()方法:
- 语法:文件对象.readlines()
- 注:readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
- 读出数据的数据类型是列表
-
readline方法:
- 语法:文件对象.readline()
- 注:一次读取一行
- 读出数据的数据类型是字符串
-
for循环读取文件行
-
语法:for line in open("D:/测试.txt","r") print(line)
-
注意:每一行line临时变量,就记录了文件的一行数据
for line in open("D:/测试.txt", "r"): print(line)
-
-
-
关闭文件
-
close() 关闭文件对象
- 语法:文件.close()
- 注:通过close,关闭文件对象,也就是关闭对文件的占用
-
with open 语法
- 语法:with open("D:/ 测试.txt","r") as f: f1 = f.readlines()
- 注:with open 可以通过操作完成后自动关闭文件
-
案例:
-
题目:
-
代码:
# 方法1:比较笨拙,是菜鸟作者自己想出来的,仅提供参考 # 自动进行文件关闭 with open("D:/测试.txt", "r") as f: cnt = 0 f1 = f.read() # 进行字符串的分割 最终得到一个列表对象 my_list = f1.split("\n") for l in my_list: l1 = l.split(" ") for l2 in l1: if l2 == "itheima": cnt += 1 print(f"此文件中itheima中出现的次数是{cnt}") # 方法2:采用read()方法读,最后用count()进行查找 f = open("D:/测试.txt", "r") f1 = f.read() print(f1.count("itheima")) f.close() # 方法3: f = open("D:/测试.txt", "r", encoding="UTF-8") cnt = 0 for line in f: # l1 = line.replace("\n", " ") line = line.strip() words = line.split(" ") print(words) for l in words: if l == "itheima": cnt += 1 print(cnt)
-
-
写入文件
-
语法:文件名.write()
-
内容刷新:文件.flush()
-
注:
-
直接调用write,内容并未真正写入文件(在文件结束之前),而是积攒在程序的内存中,称之为缓冲区
-
当调用flush的时候,内容会真正写入文件
-
代码:
import time f = open("D:/测试.txt", "w", encoding="UTF-8") f.write("Hello World!!!") f.flush() time.sleep(600000)
-
特点:文件存在,会清空原有内容;文件不存在,会创建出新文件;close()方法自带flush()方法的功能
-
-
-
-
7.1.3 文件的追加
-
语法:
# 打开文件: f = open("目标文件名(文件所在的路径)",'a',encoding="UTF-8") # 文件写入: f.write("Hello World") # 内容刷新: f.flush()
-
注意:
- a模式,文件不存在会创建文件
- a模式,文件存在会在最后,追加写入文件
-
代码:
f = open("D:/test.txt", "a", encoding = "UTF-8") f.write("\n月薪过万") f.close()
-
-
7.1.4 综合案例
-
题目:
-
代码:
f = open("D:/bill.txt", "r", encoding="UTF-8") f1 = open("D:/bill1.txt", "w", encoding="UTF-8") for line in f: line = line.strip() l = line.split(",") if l[4] != "测试": f1.write(line) # 上边把换行符取消,这里再填上 f1.write("\n") else: continue f.close() f1.close()
-
结果:
-
-
-
-
8.1 Python异常、模块与包
-
8.1.1 异常
-
定义:当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的异常。’
-
遇到BUG后产生的情况:
(1) 整个程序因为一个BUG停止运行
(2)对BUG进行提醒,整个程序继续运行
-
-
8.1.2 捕获异常(处理异常)
-
作用:提前假设某处会出现异常,做好提前准备。当真的出现异常,可以有后续手段
-
捕获常规异常:
-
基本捕获语法(可以捕获所有异常):
try:# 简写版: 可能发生错误的代码 except: 如果出现异常执行的代码 #或者:用的比较多 try: 可能发生错误的代码 except Exception as e: #Exception 是顶级的异常 print("出现异常了")
-
捕获指定异常:
-
语法:
# 出现了变量未定义的异常 try: print(name) except NameError as e: print('name变量名称未定义错误')
-
代码:
# e就是异常的对象 # 异常1: try: 1/0 except ZeroDivisionError as e: print("出现了分母是0的异常") print(e) # 异常2: try: print(name) except NameError as e: print("出现了未命名的异常") print(e)
-
捕获多个异常:
-
直接上代码:
try: print(name) except (NameError, ZeroDivisionError) as e: print("出现了变量未定义 或者 除以0的异常错误")
-
els异常:
-
语法:
try: print(1) except Exception as e:# 有异常会执行 print(e) else:# 没有异常会执行 print("我是else,是没有异常的时候执行的代码")
-
异常的finally:
-
定义:finally表示的是无论是否异常都要执行的代码
-
代码:
try: f = open("D:/测试.txt", "r") except Exception as e: f = open("test.txt", "w") else: print("没有异常,真开心") finally: f.close()
-
异常的传递
-
定义:当函数func01中发生异常,并且没有捕获处理这个异常的时候,异常会传递到函数func02,当func02也没有捕获处理这个异常的时候main函数会捕获这个异常,这就是异常的传递性
-
代码:
def func01(): print("这是func01开始") num = 1/0 print("这是func01结束") def func02(): print("这是func02开始") func01() print("这是func02结束") def main(): try: func02() except Exception as e: print(f"出现异常了,异常的信息是:{e}") main()
-
-
8.1.3 Python模块
-
模块的定义:Python 模块,是一个Python文件,以**.py**结尾。模块能定义函数、类和变量,模块里也能包含可执行的代码。
-
模块的作用:python中有很多各种不同的模块,每一个模块都可以帮助我们快速的实现一些功能,一个模块就是一个工具包,每一个工具包都有各种不同的工具供我们使用进而实现各种不同的功能。
-
语法:[from 模块名] import [模块 | 类 | 变量 | 函数 | ] [as 别名] (前后中括号都可写可不写)
-
import 模块名:
-
基本语法:
import 模块名 import 模块名1,模块名2 模块名.功能名()
-
代码:
import time # 导入python内置的time模块(time.py这个代码文件) print("你好") time.sleep(5) # 通过.就可以使用模块内部的全部功能 print("我好")
-
-
from 模块名 import 功能名(或 * ):
-
基本语法:
from 模块名 import 功能名 # 一句话解决 功能名() # 拓展: from 模块名 import * # *表示全部的意思 print("您好") time(6) print("我好")
-
代码:
from time import sleep print("您好") sleep(5) print("我好") # 或者: from time import * print("您好") sleep(5) print(“我好) # 总结:from time import *跟from time的作用相同,调用不同
-
-
as定义别名:
-
基本语法:
# 模块定义别名 import 模块名 as 别名 # 功能定义别名 from 模块名 import 功能名 as 别名
-
代码:
# 模块别名 import time as tt print("你好漂亮呀") tt.sleep(3) print("我好喜欢呀") # 功能别名 from time import sleep as dd print("HI") dd(2) print("Hello")
-
-
制作自定义模块:
-
案例:新建一个Python文件,命名为my_model.py,并定义test函数
-
代码:
# 导入模块 import my_model my_model.test(1, 2) # 或导入功能 from my_model import test test(1, 2)
-
注意:
-
当导入多个模块时候,且模块内有同名功能,当调用这个同名功能的时候,用到的是后面导入的模块的功能。
-
def test(a, b): print(a-b) def test(a, b): print(a+b) from my_model import test #这个功能的导入失效 from my_model1 import test test(5, 3)
-
-
_ _ main_ _变量:
-
_ _ main_ 变量是python中一个特殊的内置变量名,表示当前执行模块(文件)的名称, _ _ main _ _ 在不同的上下文有不同的作用。
(1)当一个Python模块作为主程序直接运行时,_ _ main _ 被设置为脚本的名称。即 if _ _ name _ _ == ' _ _main _ _':
# myscript.py def main(): # 主程序的逻辑代码 if __name__ == '__main__': main()
(2)当一个模块被导入到其他模块中,_ _ main _ 不再表示该模块的名称,而是表示模块本事。 _ _ main _ _不会被执行。
-
作用:这种机制我们可以在模块中定义一些用于测试的代码,而这些代码在模块被导入时不会执行。
-
-
_ all _变量:
-
定义:如果一个模块文件中有'_ all _ ' 变量,当使用 from xxx import * 导入时,只能导入这个列表中的元素(即:控制import * 能导入的内容)
-
代码
# 在一个Python文件中定义两个功能 _all_ = ['test_A'] def test_A(): print("testA") def test_B(): print("testB") # 导入另一个Python文件中时 from my_model import * test_A() # 只能使用test_A函数 test_B() # 不可以用
-
-
-
-
-
8.1.4 Python包
-
定义:从物理上看,包就是一个文件夹,在该文件夹下包含一个_ init _ . py文件,该文件夹可用于包含多个模块文件;从逻辑上看,包的本质依然是模块。
- 即:Python包 = 模块文件 + _ int _ **.**py 文件
-
自定义包:
-
代码:
创建一个包 导入自定义包中的模块,并使用 通过模块导入 import my_package.model1 import my_package.model2 my_package.model1.info_print1() my_package.model2.info_print2() 通过功能导入 from my_package.model1 import info_print1 info_print1() from my_package.model2 import info_print2 info_print2()
-
python包中也可以定义 _ _ all _ _变量,使用方法和作跟上边相似,功能函数必须写在变量列表中才行。
-
-
安装第三方包:
-
第三方包的定义:一个包,就是一堆同类型功能的集合体。
-
安装步骤:
# 在命令提示符内: pip install 包名称 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称
-
-
总结:
-
包 ——> 模块 ——> 功能函数
-
综合案例:
-
题目:
-
代码:
# 自定义包的两个功能模块: # file_util.py模块 # 功能1: def print_file_info(file_name): f = None try: f = open(file_name, "r", encoding="UTF-8") print("被打开的文件是:") print(f.read()) except Exception as e: print(f"出现文件未存在的异常{e}") finally: # 如果变量是None,表示是flase,如果不是None,表示是True if f: f.close() # 功能2: def append_to_file(file_name, data): f = open(file_name, "a", encoding="UTF-8") f.write(data) f.close() if __name__ == '__main__': print_file_info("D:/abc.txt") append_to_file("D:/测试.txt", "冯珑你真帅") # str_util.py模块: # 功能1: def str_reverse(s): n_s = s[::-1] print(f"反转后的字符串:{n_s}") # 功能2: def substr(s, x, y): n_s = s[x:y:1] print(f"切片后的字符串:{n_s}") if __name__ == '__main__': str_reverse("123456") substr("fenglongjiayou", 1, 5) # Python文件中的调用: # 通过模块调用 import my_package.str_util import my_package.file_util my_package.str_util.str_reverse("abcdefgh") my_package.file_util.print_file_info("D:/测试.txt") # 通过模块的功能调用 from my_package.str_util import str_reverse str_reverse("家和万事兴") from my_package.file_util import print_file_info print_file_info("D:/测试.txt")
-
-
-
-
8.1.5 Python基础综合案例:
-
前置JSON的了解:
-
JSON是一种轻量级的数据交互格式。可以按照JSON指定的格式去组织和封装数据
-
JSON本质上是一个带有特定格式的字符串
-
主要功能:JSON就是一种在各个编程语言中流通的数据格式,负责不同语言中的数据传递和交互
-
Python的数据格式:
# Python对象数据的格式可以是: 字典 {"name":"admin","age":18} # 也可以是列表,但是由字典组成的 [{"name":"admin","age":18},{"name":"root","age":16},{"name":"张三","age:20"}]
-
-
JSON和Python之间的数据转换:
-
重点:Python列表中的字典对象转换成JSON的字符串
-
Python字典对象 向 JSON的字符串之间的转换:json_str = json.dumps(data)
import json # 将列表中的字典转换为JSON字符串 data = [{"name": "张大仙", "age": 11}, {"name": "王大锤", "age": 13}, {"name": "赵小虎", "age": 16}] # 要转换的Python中有中文的话,用ensure_ascii=False可以将ASCII码显示中文 json_str = json.dumps(data, ensure_ascii=False) print(type(json_str)) print(json_str) # 将字典转换为JSON字符串 d = {"name": "周杰轮", "addr": "台北"} json_str = json.dumps(d, ensure_ascii=False) print(type(json_str)) print(json_str)
-
JSON的字符串 向 Python的字典对象的转换:py_list = json.loads(s)
# s是JSON中的字符串 用单引号‘ ’表示 # 转换成列表 s = '[{"name": "张大仙", "age": 11}, {"name": "王大锤", "age": 13}, {"name": "赵小虎", "age": 16}]' Py_list = json.loads(s) print(type(Py_list)) print(Py_list) # 转换成字典 s1 = '{"name": "周杰轮", "addr": "台北"}' py_dict = json.loads(s1) print(type(py_list)) print(py_list)
-
-
pyecharts模块介绍:
-
pyecharts模块的配置:
-
全局配置选项:图像的标题,图像的图例,工具箱配置项
-
set_global_opts方法:这里全局配置选项可以通过set_global_opts进行配置
# 导包,导入Line功能构建折线图对象 from pyecharts.charts import Line # 导包,导入各种设置图像功能的包 from pyecharts.options import TitleOpts, LegendOpts, ToolboxOpts, VisualMapOpts # 得到折线图对象 line = Line() # 添加x轴数据 line.add_xaxis(["中国", "美国", "英国"]) # 添加y轴数据 line.add_yaxis("GDP", [30, 20, 10]) # 设置全局配置项set_global_opts来 配置 图表 # pos_bottom 具体底部的距离 line.set_global_opts( # 配置图表的标题 title_opts=TitleOpts(title="GDP展示", pos_left="center", pos_bottom="1%"), # 配置图例 legend_opts=LegendOpts(is_show=True), # 配置工具栏 toolbox_opts=ToolboxOpts(is_show=True), # 控制视觉影像(可视化) visualmap_opts=VisualMapOpts(is_show=True) ) # 生成图表 line.render()
-
-
系列配置选项:具体的轴数据进行配置
-
案例:美日印三国的折线图
-
重点:给折线图添加数据的数据类型是列表
-
代码:
import json # 导入Line功能构建折线图对象 from pyecharts.charts import Line # 导包,导入各种设置图像功能的包 from pyecharts.options import TitleOpts, LegendOpts, ToolboxOpts, VisualMapOpts, LabelOpts # 处理数据 f_us = open("D:/BaiduNetdiskDownload/资料/可视化案例数据/折线图数据/美国.txt", "r", encoding="UTF-8") f_jp = open("D:/BaiduNetdiskDownload/资料/可视化案例数据/折线图数据/日本.txt", "r", encoding="UTF-8") f_in = open("D:/BaiduNetdiskDownload/资料/可视化案例数据/折线图数据/印度.txt", "r", encoding="UTF-8") us_data = f_us.read() # 美国的全部内容 in_data = f_in.read() # 印度的全部内容 jp_data = f_jp.read() # 日本的全部内容 # 去掉不符合JSON规范的开头 us_data = us_data.replace("jsonp_1629344292311_69436(", "") in_data = in_data.replace("jsonp_1629350745930_63180(", "") jp_data = jp_data.replace("jsonp_1629350871167_29498(", " ") # 去掉不符合JSON规范的结尾 us_data = us_data[:-2:] in_data = in_data[:-2:] jp_data = jp_data[:-2:] # JSON字符串向字典转换 us_dict = json.loads(us_data) in_dict = json.loads(in_data) jp_dict = json.loads(jp_data) # 简化数据 us_dict = us_dict["data"][0]["trend"] in_dict = in_dict["data"][0]["trend"] jp_dict = jp_dict["data"][0]["trend"] # x轴数据 us_x_data = us_dict["updateDate"][:314] in_x_data = in_dict["updateDate"][:269] jp_x_data = jp_dict["updateDate"][:315] # y轴数据 us_y_data = us_dict["list"][0]["data"][:314] in_y_data = in_dict["list"][0]["data"][:269] jp_y_data = jp_dict["list"][0]["data"][:315] # 生成图表 line = Line() # 添加x轴数据 line.add_xaxis(in_x_data) line.add_xaxis(us_x_data) line.add_xaxis(jp_x_data) # 添加y轴数据 line.add_yaxis("美国确诊人数", us_y_data, label_opts=LabelOpts(is_show=False)) line.add_yaxis("印度确诊人数", in_y_data, label_opts=LabelOpts(is_show=False)) line.add_yaxis("日本确诊人数", jp_y_data, label_opts=LabelOpts(is_show=False)) # 设置全局选项 line.set_global_opts( # 标题设置 title_opts=TitleOpts(title="2020年美日印三国确诊人数对比折线图", pos_left="center", pos_bottom="1%") ) # 调用render方法,生成图表 line.render() # 关闭文件对象 f_us.close() f_in.close() f_jp.close()
-
-
数据可视化案例:
-
地图:给地图添加的数据类型是列表,列表的内部有元组组成。
-
案例:河南省各市的疫情地图
-
代码
# 导包 import json from pyecharts.charts import Map from pyecharts.options import TitleOpts, VisualMapOpts # 打开文件 f = open("D:/BaiduNetdiskDownload/资料/可视化案例数据/地图数据/疫情.txt", "r", encoding="UTF-8") china_data = f.read() f.close() china_dict = json.loads(china_data) hn_data = china_dict["areaTree"][0]["children"][3]["children"] hn_list = [] for x in hn_data: if x["name"] == "济源示范区": x["name"] = "济源" hn_name = x["name"]+"市" hn_confirm = x["total"]["confirm"] hn_list.append((hn_name, hn_confirm)) # 创建地图对象 map1 = Map() # 向地图输入数据 map1.add("各市确诊人数", hn_list, "河南") # 设置全局配置,定制分段的视觉映射 map1.set_global_opts( # 设置地图的标题 title_opts=TitleOpts(title="河南省疫情地图", pos_left="center", pos_bottom="1%"), visualmap_opts=VisualMapOpts( is_show=True, is_piecewise=True, pieces=[ {"min": 1, "max": 99, "lable": "1-99个人", "color": "#CCFFFF"}, {"min": 100, "max": 499, "lable": "1-99个人", "color": "#FF34B3"}, {"min": 500, "max": 999, "lable": "1-99个人", "color": "#FF00FF"}, {"min": 1000, "max": 4999, "lable": "1-99个人", "color": "#1E90FF"}, {"min": 5000, "max": 9999, "lable": "1-99个人", "color": "#2E8B57"}, {"min": 10000, "lable": "10000+", "color": "#FFFF00"} ] ) ) # 绘图 map1.render("河南省疫情地图.html")
-
结果:
-
柱状图:给柱状图添加的数据类型是列表,列表的内部有元组组成
-
创建时间线对象,并设置主题颜色
# 需要导入包 from pyecharts.globals import ThemeType # 在创建时间线时设置 timeline = Timeline({"theme": ThemeType.LIGHT})
-
主题颜色的选择:
-
-
自动播放的设置:(重点)
timeline.add_schema( # 自动播放的时间间隔,单位毫秒 play_interval=1000, # 是否显示时间线 is_timeline_show=True, # 是否自动播放 is_auto_play=True, # 是否循环播放 is_loop_play=True )
-
案例:中、美、英GDP的分布
-
代码:
# 导包 from pyecharts.charts import Bar, Timeline from pyecharts.globals import ThemeType from pyecharts.options import * # 构建柱状图对象 bar1 = Bar() # 添加x轴数据 bar1.add_xaxis(["中国", "美国", "英国"]) # 将y轴数据值写在轴的右侧 label_opts=LabelOpts(position="right") # 添加y轴数据 bar1.add_yaxis("GDP", [30, 20, 10], label_opts=LabelOpts(position="right")) # 反转x轴和y轴 bar1.reversal_axis() # 创建第二个对象 bar2 = Bar() bar2.add_xaxis(["中国", "美国", "英国"]) bar2.add_yaxis("GDP", [50, 30, 20], label_opts=LabelOpts(position="right")) bar2.reversal_axis() # 创建第三个对象 bar3 = Bar() bar3.add_xaxis(["中国", "美国", "英国"]) bar3.add_yaxis("GDP", [70, 60, 10], label_opts=LabelOpts(position="right")) bar3.reversal_axis() # 创建时间线对象 timeline = Timeline({"theme": ThemeType.CHALK}) timeline.add(bar1, "2021年GDP") timeline.add(bar2, "2022年GDP") timeline.add(bar3, "2023年GDP") # 自动播放设置 timeline.add_schema( # 自动播放的时间间隔,单位毫秒 play_interval=1000, # 是否显示时间线 is_timeline_show=True, # 是否自动播放 is_auto_play=True, # 是否循环播放 is_loop_play=True ) # 用时间线对象绘图 timeline.render("基础柱状图.html")
-
GDP动态柱状图绘制:
-
列表的sort方法并配合lambda匿名函数完成列表排序(即对列表中的列表进行排序)
-
使用方式:
-
列表.sort(key = 选择排序依据的函数,reverse = True|False)
- 参数key,是要求传入一个函数,表示将列表的每一个元素都传入函数中,返回排序的依据
- 参数reverse,是否反转排序结果,True表示降序,False表示升序。
-
代码部分:
# 列表的sort方法 my_list = [["a", 33], ["b", 55], ["c", 11]] # 排序,基于带名函数 def choose_sort_key(element): return element[1] my_list.sort(key=choose_sort_key, reverse=True) print(my_list) # 基于带有lambda的匿名函数 my_list.sort(key=lambda element: element[1], reverse=False) print(my_list)
-
-
案例:全世界前8GDP数据
-
代码:
# 导包 from pyecharts.charts import Bar, Timeline # 对柱状图作各种修饰功能的包 from pyecharts.options import * # 导入主题的包 from pyecharts.globals import ThemeType f = open("D:/BaiduNetdiskDownload/资料/可视化案例数据/动态柱状图数据/1960-2019全球GDP数据.csv", encoding="GB2312") data_lines = f.readlines() data_lines1 = f.read() data_lines2 = f.readline() # 关闭文件 f.close() # 删除第一条数据 data_lines.pop(0) # 将数据转换为字典储存,格式为: # 先定义一个字典对象 data_dict = {} for line in data_lines: # 年份 year = int(line.split(",")[0]) # 国家 country = line.split(",")[1] # GDP数据 gdp = float(line.split(",")[2]) # 如果这个年份的key值存在,直接在这个key的value下的列表中添加列表 try: data_dict[year].append([country, gdp]) # 如果这个年份的key值不存在,这个key的value下创建一个空的列表 except KeyError: data_dict[year]=[] data_dict[year].append([country, gdp]) # print(data_dict[1960]) # 排序年份 sorted_year_list = sorted(data_dict.keys()) # 建立时间线对象 timeline = Timeline({"theme": ThemeType.LIGHT}) for year in sorted_year_list: data_dict[year].sort(key=lambda element: element[1], reverse=False) year_data = data_dict[year][-8::1] x_data = [] y_data = [] # 获取各个年份的x轴和y轴数据 for country_gdp in year_data: x_data.append(country_gdp[0]) # x轴 y_data.append(country_gdp[1]/100000000) # y轴 # 建立柱状图对象 bar1 = Bar() bar1.add_xaxis(x_data) bar1.add_yaxis("GDP(亿)", y_data, label_opts=LabelOpts(position="right")) # 反转x轴和y轴 bar1.reversal_axis() # 设置柱状图的标题 bar1.set_global_opts( title_opts=TitleOpts(title=f"{year}年全球前8GDP数据") ) # 将每一年的柱状图加到时间线上 timeline.add(bar1, str(year)) # 设置时间线自动播放 timeline.add_schema( play_interval=1000, is_timeline_show=True, is_auto_play=True, is_loop_play=True ) # 用时间线对象绘图 timeline.render("全世界前8GDP柱状图.html")
-
-
-
-
-
-