【全篇】Python从零基础到入门

文章目录

  • 第一章 基础语法
    • 1.字面量
    • 2.注释
    • 3.变量
    • 4.数据类型
    • 5.数据类型转换
    • 6.标识符
    • 7.运算符
    • 8.字符串拓展
      • 1.字符串的三种定义方式
      • 2.字符串拼接(不用)
      • 3.字符串格式化(了解)
      • 4.格式化的精度控制
      • 5.字符串格式化2(常用)
      • 6.对表达式格式化
      • 小练习
    • 9.数据输入
    • 10.python中定义字符串前面加b、u、r的含义
  • 第二章 判断语句
    • 1.布尔类型
    • 2.if语句基本格式
    • 3.if else 语句
    • 4.if elif else语句
    • 5.判断语句的嵌套
  • 第三章 循环语句
    • 1.while循环
      • 1.基本语法
      • 2.基础案例
      • 3.嵌套应用
      • 4.嵌套案例
    • 2.for 循环
      • 1.for循环的基本语法
      • 2.range语句
      • 3.变量作用域
      • 4.for循环的嵌套应用
      • 5.循环中断:break ,continue
  • 第四章 函数
    • 1.函数介绍
    • 2.函数定义
    • 3.函数参数
    • 4.函数返回值
      • None类型
    • 5.函数说明文档
    • 6.函数嵌套调用
    • 7.变量作用域
      • 1.局部变量
      • 2.全局变量
      • global关键字
  • 第五章函数进阶
  • 1.函数的多返回值
  • 2.函数的多种传参方式
  • 3.匿名函数
    • 1.函数作为参数传递
    • 2.lambda匿名函数
  • 第六章数据容器
  • 1.初识数据容器
  • 2.数据容器:list(列表)
    • 1.列表的定义
    • 2.列表的下标索引
    • 3.列表的常用操作(增删改查)
      • 3.1列表的查询功能
      • 3.2列表的修改功能(方法):
        • 插入元素:
        • 追加元素:
        • 删除元素
    • 总览
    • 综合练习
  • 4.list(列表)的遍历
    • while循环
    • for循环
    • 练习案例
  • 3.数据容器:tuple(元组)
    • 1.元组的定义
    • 2.元组的操作
    • 3.元组的特点
    • 练习案例
  • 4.数据容器:str(字符串)
    • 1.字符串的下标(索引)
    • 2.字符串的常用操作
      • 1.查找特定字符串的下标索引值
      • 2.字符串的替换
      • 3.字符串的分割
      • 4.字符串的规整操作
      • 5.统计字符串中某字符串的出现次数
      • 6.统计字符串的长度
    • 字符串常用操作汇总
  • 5.数据容器(序列)的切片
  • 6.数据容器:set(集合)
    • 1.集合的特点
    • 2.集合的定义
    • 3.集合的常见操作
  • 集合常用功能总结
  • 综合练习
  • 7.数据容器:dict(字典、映射)
    • 1.字典的含义
    • 2.字典的定义
    • 3.字典的常用操作
    • 总结
    • 练习题
  • 数据容器对比
  • 数据容器通用操作
  • 拓展:字符串比大小
  • 第七章 文件操作
  • 1.文件的编码
  • 2. 文件的读取
    • open()打开函数
    • read()方法:
    • close() 关闭文件对象
    • with open 语法
  • 3.文件的写入
  • 4.文件的追加
  • 5.文件备份案例
  • 第八章 Pyhton异常、模块、包
  • 1.异常
  • 2.异常捕获
  • 3.异常的传递
  • 4.python模块
    • 1.模块导入方式
    • 2.as定义别名
  • 5.自定义模块
  • 6.测试模块
  • 7.__ all __
  • 8.自定义包
  • 9.安装第三方包

第一章 基础语法

1.字面量

字面量:在代码中,被写下来的的固定的值,称之为字面量

类型描述说明
数字(Number)支持整数(int)浮点数(float)复数(complex)布尔(bool)整数(int),如:10、-10
浮点数(float),如:13.14、-13.14
复数(complex),如:4+3j,以j结尾表示复数
布尔(bool)表达现实生活中的逻辑,即真和假,True表示真,False表示假。True本质上是一个数字记作1,False记作0
字符串(String)描述文本的一种数据类型字符串(string)由任意数量的字符组成
列表(List)有序的可变序列Python中使用最频繁的数据类型,可有序记录一堆数据
元组(Tuple)有序的不可变序列可有序记录一堆不可变的Python数据集合
集合(Set)无序不重复集合可无序记录一堆不重复的Python数据集合
字典(Dictionary)无序Key-Value集合可无序记录一堆Key-Value型的Python数据集合

字符串(string),又称文本,是由任意数量的字符如中文、英文、各类符号、数字等组成。所以叫做字符的串

在这里插入图片描述

  • print(10),输出整数10
  • print(13.14),输出浮点数13.14
  • print(“我爱编程”),输出字符串:我爱编程

2.注释

注释:在程序代码中对程序代码进行解释说明的文字。
作用:注释不是程序,不能被执行,只是对程序代码进行解释说明,让别人可以看懂程序代码的作用,能够大大增强程序的可读性。

  • 单行注释:以 #开头,#右边 的所有文字当作说明,而不是真正要执行的程序,起辅助说明作用

    #我是单行注释
    print("Hello World")
    
    运行结果:
    Hello World
    
  • 多行注释: 以 一对三个双引号 引起来 ( “”“ 注释内容 ”“” )来解释说明一段代码的作用使用方法

    """
    我是多行注释
    我可以写多行
    """
    print("hello,world")
    
    运行结果:
    hello,world
    

3.变量

变量:在程序运行时,能储存计算结果或能表示值的抽象概念。
简单的说,变量就是在程序运行时,记录数据用的

在这里插入图片描述

  • 变量,从名字中可以看出,表示“量”是可变的。所以,变量的特征就是,变量存储的数据,是可以发生改变的。
  • 变量的目的是存储运行过程的数据。存储的目的是为了:重复使用
#将数字10存到data变量里
data = 10

4.数据类型

数据是有类型的。目前在入门阶段,我们主要接触如下三类数据类型:

类型描述说明
string字符串类型用引号引起来的数据都是字符串
int整型(有符号)数字类型,存放整数 如 -1,10, 0 等
float浮点型(有符号)数字类型,存放小数 如 -3.14, 6.66

那么,问题来了,如何验证数据的类型呢?

我们可以通过type()语句来得到数据的类型:
语法:type(被查看类型的数据)

示例代码:

#1.用print语句,直接输出类型信息
print(type("这是字符串"))
print(type(666))
print(type(3.14))

#运行结果
<class 'str'>
<class 'int'>
<class 'float'>

在这里插入图片描述

5.数据类型转换

数据类型之间,在特定的场景下,是可以相互转换的,如字符串转数字、数字转字符串等

跟C语言里面的强制转换很像

数据类型转换,将会是我们以后经常使用的功能。
如:

  • 从文件中读取的数字,默认是字符串,我们需要转换成数字类型
  • 后续学习的input()语句,默认结果是字符串,若需要数字也需要转换
  • 将数字转换成字符串用以写出到外部系统等等

常见的转换语句

语句(函数)说明
int(x)将x转换为一个整数
float(x)将x转换为一个浮点数
str(x)将对象 x 转换为字符串

同前面学习的type()语句一样,这三个语句,都是带有结果的(返回值)
我们可以用print直接输出
或用变量存储结果值

  1. 任何类型,都可以通过str(),转换成字符串

  2. 字符串内必须真的是数字,才可以将字符串转换为数字

  3. 浮点数转整数会丢失精度,也就是小数部分

在这里插入图片描述

6.标识符

在Python程序中,我们可以给很多东西起名字,比如:

  • 变量的名字
  • 方法的名字
  • 类的名字,等等
    这些名字,我们把它统一的称之为标识符,用来做内容的标识。
    所以,标识符:是用户在编程的时候所使用的一系列名字,用于给变量、类、方法等命名。

标识符命名规则中,只允许出现:

  1. 英文
  2. 中文(不推荐使用中文)
  3. 数字(数字不可以开头)
  4. 下划线(_)
  • 区分大小写

  • 不可使用关键字

    在这里插入图片描述

    变量的命名规范

    • 见名知意
    • 下划线命名法
    • 英文字母全小写

7.运算符

a = 10,b = 20

运算符描述实例
+两个对象相加 a + b 输出结果 30
-得到负数或是一个数减去另一个数 a - b 输出结果 -10
*两个数相乘或是返回一个被重复若干次的字符串 a * b 输出结果 200
/b / a 输出结果 2
//取整除返回商的整数部分 9//2 输出结果 4 , 9.0//2.0 输出结果 4.0
%取余返回除法的余数 b % a 输出结果 0
**指数a**b 为10的20次方, 输出结果 100000000000000000000

赋值运算符

运算符描述实例
=赋值运算符把 = 号右边的结果 赋给 左边的变量,如 num = 1 + 2 * 3,结果num的值为7

复合赋值运算符

运算符描述实例
+=加法赋值运算符c += a 等效于 c = c + a
-=减法赋值运算符c -= a 等效于 c = c - a
*=乘法赋值运算符c *= a 等效于 c = c * a
/=除法赋值运算符c /= a 等效于 c = c / a
%=取模赋值运算符c %= a 等效于 c = c % a
**=幂赋值运算符c ** = a 等效于 c = c ** a
//=取整除赋值运算符c //= a 等效于 c = c // a

8.字符串拓展

1.字符串的三种定义方式

  • 单引号方式 name = ‘张三’
  • 双引号方式 name = “张三”
  • 三引号方式 name = ”’ 张三 “‘

字符串的引号嵌套

  1. 单引号定义法,可以内含双引号
  2. 双引号定义法,可以内含单引号
  3. 可以使用转移字符(\)来将引号解除效用,变成普通字符串

print(“ I\ ‘m ”)

2.字符串拼接(不用)

  1. 变量过多,拼接起来实在是太麻烦了
  2. 字符串无法和数字或其它类型完成拼接。

在这里插入图片描述

字符串无法和非字符串变量进行拼接。因为类型不一致,无法接上

3.字符串格式化(了解)

name = "小明"
message = "大家好,我叫%s"%name
print(message)

#运行结果:
大家好,我叫小明

其中的,%s

  • % 表示:我要占位

  • s 表示:将变量变成字符串放入占位的地方
    所以,综合起来的意思就是:我先占个位置,等一会有个变量过来,我把它变成字符串放到占位的位置

Python中,其实支持非常多的数据类型占位
最常用的是如下三类:

格式符号转化
%s将内容转换成字符串,放入占位位置
%d将内容转换成整数,放入占位位置
%f将内容转换成浮点型,放入占位位置

多个变量占位,变量要用括号括起来,并按照占位的顺序填入

str ="字符串abc"
int = 10
float = 3.14
print("这是字符串%s,这是整型数%d,这是浮点数%f"%(str,int,float))

#运行结果:
这是字符串字符串abc,这是整型数10,这是浮点数3.140000

4.格式化的精度控制

我们可以使用辅助符号"m.n"来控制数据的宽度和精度

  • m,控制宽度,要求是数字(很少使用)(设置的宽度小于数字自身,不生效)

  • .n,控制小数点精度(要求是数字,会进行小数的四舍五入)
    示例:

  • %5d:表示将整数的宽度控制在5位,(如数字11,被设置为5d,就会变成:空格 空格 空格 11,用三个空格补足宽度)

  • %5.2f:表示将宽度控制为5,将小数点精度设置为2, 小数点和小数部分也算入宽度计算。

    (如,对11.345设置了%7.2f 后,结果是: 空格 空格 11.35。2个空格补足宽度,小数部分限制2位精度后,四舍五入为 .35%.2f:表示不限制宽度,只设置小数点精度为2,如11.345设置%.2f后,结果是11.35)

  • %.2f:表示不限制宽度,只设置小数点精度为2,(如11.345设置%.2f后,结果是11.35)

在这里插入图片描述

5.字符串格式化2(常用)

语法:f”{变量} {变量}”的方式进行快速格式化

这种写法不做精度控制,也不理会类型。适用于快速格式化字符串(可以说是原样输出了)

在这里插入图片描述

6.对表达式格式化

表达式:一条具有明确执行结果的代码语句
如:
1 + 1、5 * 2,就是表达式,因为有具体的结果,结果是一个数字
又或者,常见的变量定义:
name = “张三” age = 11 + 11
等号右侧的都是表达式呢,因为它们有具体的结果,结果赋值给了等号左侧的变量。

在这里插入图片描述

在无需使用变量进行数据存储的时候,可以直接格式化表达式,简化代码哦

至此,已经学会了两种字符串格式化的方法

  • f"{表达式}"

  • “%s%d%f” % (表达式、表达式、表达式)

小练习

在这里插入图片描述

name,公司名
stock_price,当前股价
stock_code,股票代码
stock_price_daily_growth_factor,股票每日增长系数,浮点数类型,比如1.2
growth_days,增长天数

name = "橘猫"
stock_price = 19.99
stock_code = 003032
stock_price_daily_growth_factor = 1.2
growth_days = 7
price = stock_price*stock_price_daily_growth_factor**growth_days
print(f"公司{name},股票代码{stock_code},当前股价{stock_price}")
print("每日增长系数%d,经过%d天的增长后,股价达到了:%d"%(stock_price_daily_growth_factor,growth_days,price))

9.数据输入

关键词:input()函数

  1. input()语句的功能是,获取键盘输入的数据
  2. 可以使用:input(提示信息),用以在使用者输入内容之前显示提示信息。
  3. 要注意,无论键盘输入什么类型的数据,获取到的数据永远都是字符串类型

在这里插入图片描述

input不管你输入的什么数据类型,它输出的统一都是字符串,所以如果我们需要别的类型时,需要进行强转

10.python中定义字符串前面加b、u、r的含义

1.1 基本格式

str = b"xxxx"
str = u"xxxx"
str = r"xxxx"
str = f"xxxx"

1.2 描述及对比
(1)字符串前面加b表示后面字符串是bytes类型,以便服务器或浏览器识别bytes数据类型;
(2)字符串前面加u表示以Unicode格式进行编码,往往用来解决中文乱码问题,一般英文字符串基本都可以正常解析,而中文字符串必须表明用什么编码,否则就会乱码。
(3)字符串前面加r表示以raw string格式进行定义,可以防止字符串规避反斜杠\的转义。
例如:

str1 = "\thello"
str2 = r"\thello"
print("str1 =",str1)
print("str2 =",str2)

输出

str1 =  	hello
str2 = \thello

(4)字符串前面加f表示能支持大括号里面的表达式。
例如:

python = "蟒蛇"
print("我要好好学{python}!")
print(f"我要好好学{python} !")

输出

我要好好学{python} !
我要好好学蟒蛇 !

(5)在python3中,bytes和str的相互转换

str.encode('utf-8')

bytes.decode('utf-8')

例如:

print("你好".encode(encoding="utf-8"))

输出b’\xe4\xbd\xa0\xe5\xa5\xbd’

print(b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode())

输出你好

往往用于图片、音视频等文件的读写时,可用bytes数据。

第二章 判断语句

1.布尔类型

在这里插入图片描述

布尔类型的字面量:

  • True 表示真(是、肯定)
  • False 表示假 (否、否定)

定义变量存储布尔类型数据:变量名称 = 布尔类型字面量

布尔类型不仅可以自行定义,,同时也可以通过计算的来。

也就是使用比较运算符进行比较运算得到布尔类型的结果。

在这里插入图片描述

在这里插入图片描述

运算符描述示例
==判断内容是否相等,满足为True,不满足为False如a=3,b=3,则(a == b) 为 True
!=判断内容是否不相等,满足为True,不满足为False如a=1,b=3,则(a != b) 为 True
>判断运算符左侧内容是否大于右侧满足为True,不满足为False如a=7,b=3,则(a > b) 为 True
<判断运算符左侧内容是否小于右侧满足为True,不满足为False如a=3,b=7,则(a < b) 为 True
>=判断运算符左侧内容是否大于等于右侧满足为True,不满足为False如a=3,b=3,则(a >= b) 为 True
<=判断运算符左侧内容是否小于等于右侧满足为True,不满足为False如a=3,b=3,则(a <= b) 为 True

2.if语句基本格式

if 要判断的条件:

​ 条件成立时,要做的事

#1.定义变量
age = 30
#2.进行判断 
if age >= 18:
	print("我已经成年了")

判断语句的结果,必须是布尔类型 True 或 False
True会执行if内的代码语句
False则不会执行

在这里插入图片描述

在这里插入图片描述

3.if else 语句

if 条件1:
    条件1满足应做的事情
    条件1满足应做的事情
    ......
else:
    不满足条件时要做的事情1
    不满足条件时要做的事情2

在这里插入图片描述

  1. else后,不需要判断条件

  2. 和if的代码块一样,else的代码块同样需要4个空格作为缩进

4.if elif else语句

elif 将elseif缩写了

if 条件1:
    条件1满足应做的事情
    条件1满足应做的事情
    ......
elif 条件2:
    条件2满足应做的事情
    条件2满足应做的事情
    ......
else:

在这里插入图片描述

使用if elif else的注意点有:

  • elif可以写多个
  • 判断是互斥且有序的,上一个满足后面的就不会判断了
  • 可以在条件判断中,直接写input语句,节省代码量

5.判断语句的嵌套

字面意思就是一个if语句里面又套了一个if语句

基础语法:

if 条件1:
    要做什么事
    if 条件2:
    	要做什么事

嵌套的关键点,在于:空格缩进
通过空格缩进,来决定语句之间的:层次关系

在这里插入图片描述

如图:

  • 判断有2层
  • 当外层if满足条件(图中编号1)时,才会执行内层if判断(图中编号2)
  • 当外层if(编号1)不满足,直接执行外层esle

第三章 循环语句

1.while循环

1.基本语法

while 条件:
	执行的事情1
    执行的事情2
    执行的事情3
    
#示例代码    
i = 0
while i<100:
    print("hello,world")
    i+=1
  1. while的条件需得到布尔类型,True表示继续循环,False表示结束循环

  2. 需要设置循环终止的条件,如i += 1配合 i < 100,就能确保100次后停止,否则将无限循环

  3. 空格缩进和if判断一样,都需要设置

2.基础案例

设置一个范围1-100的随机整数变量,通过while循环,配合input语句,判断输入的数字是否等于随机数

  • 无限次机会,直到猜中为止
  • 每一次猜不中,会提示大了或小了
  • 猜完数字后,提示猜了几次

提示:
无限次机会,终止条件不适合用数字累加来判断,可以考虑布尔类型本身(True or False)
需要提示几次猜中,就需要提供数字累加功能

"""
演示while循环的基础案例 - 猜数字
"""

# 获取范围在1-100的随机数字
import random
num = random.randint(1, 100)
# 定义一个变量,记录总共猜测了多少次
count = 0

# 通过一个布尔类型的变量,做循环是否继续的标记
flag = True
while flag:
    guess_num = int(input("请输入你猜测的数字:"))
    count += 1
    if guess_num == num:
        print("猜中了")
        # 设置为False就是终止循环的条件
        flag = False
    else:
        if guess_num > num:
            print("你猜的大了")
        else:
            print("你猜的小了")

print(f"你总共猜测了{count}次")

3.嵌套应用

while 条件1:
	执行的事情1
    执行的事情2
    执行的事情3
    while 条件2:
        执行的事情1
        执行的事情2
        执行的事情3

嵌套循环的使用难点:循环条件的控制,层次越多越复杂,需要细心+耐心

"""
演示while循环的嵌套使用
嵌套循环需要注意的地方:
	1.注意条件的控制,避免无限循环
	2.多层嵌套,主要空格缩进来确定层次关系

"""

# 外层:表白100天的控制
# 内层:每天的表白都送10只玫瑰花的控制

i = 1
while i <= 100:
    print(f"今天是第{i}天,准备表白.....")

    # 内层循环的控制变量
    j = 1
    while j <= 10:
        print(f"送给小美第{j}只玫瑰花")
        j += 1

    print("小美,我喜欢你")
    i += 1

print(f"坚持到第{i - 1}天,表白成功")

补充知识:

end = ‘ ’

  1. 默认print语句输出内容会自动换行

在这里插入图片描述

  1. 在print语句中,加上 end=’’ 即可输出不换行

在这里插入图片描述

制表符\t

在字符串中,有一个特殊符号:\t,效果等同于在键盘上按下:tab键。
它可以让我们的多行字符串进行对齐。

在这里插入图片描述


4.嵌套案例

"""
演示使用while的嵌套循环
打印输出九九乘法表
"""

# 定义外层循环的控制变量
i = 1
while i <= 9:

    # 定义内层循环的控制变量
    j = 1
    while j <= i:
        # 内层循环的print语句,不要换行,通过\t制表符进行对齐
        print(f"{j} * {i} = {j * i}\t", end='')
        j += 1

    i += 1
    print()     # print空内容,就是输出一个换行

在这里插入图片描述

2.for 循环

1.for循环的基本语法

  • while循环的循环条件是自定义的,自行控制循环条件
  • for循环是一种”轮询”机制,是对一批内容进行”逐个处理”
  • 同while循环不同,for循环是无法定义循环条件的。只能从被处理的数据集中,依次取出内容进行处理。所以,理论上讲,Python的for循环无法构建无限循环(被处理的数据集不可能无限大)
#从待处理数据集中:逐个取出数据,赋值给临时变量
语法:
for 临时变量 in 待处理数据集: 
        循环满足条件时执行的代码

# 定义字符串name
name = ”itheima”

# for循环处理字符串
for x in name: 
       print(x)

练习题

"""
演示for循环的练习题:数一数有几个a
"""
# 统计如下字符串中,有多少个字母a
name = "itheima is a brand of itcast"

# 定义一个变量,用来统计有多少个a
count = 0

# for 循环统计
# for 临时变量 in 被统计的数据:
for x in name:
    if x == "a":
        count += 1

print(f"被统计的字符串中有{count}个a")

2.range语句

for 临时变量 in 待处理数据集(可迭代对象):
循环满足条件时执行的代码

语法中的:待处理数据集,严格来说,称之为:可迭代类型
可迭代类型指,其内容可以一个个依次取出的一种类型,包括:

  • 字符串
  • 列表
  • 元组等
    目前我们只学习了字符串类型,其余类型在后续章节会详细学习它们

for循环语句,本质上是遍历:可迭代对象。

语法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]

for i in range(5): 
       print(i)
        
输出:
0
1
2
3
4

3.变量作用域

在这里插入图片描述

如图代码,思考一下:红框中的print语句,能否访问到变量 i ?

规范上:不允许
实际上:可以

回看for循环的语法,我们会发现,将从数据集(序列)中取出的数据赋值给:临时变量

for 临时变量 in 待处理数据集(可迭代对象): 
   循环满足条件时执行的代码

临时变量,在编程规范上,作用范围(作用域),只限定在for循环内部

如果在for循环外部访问临时变量:

  • 实际上是可以访问到的
  • 在编程规范上,是不允许、不建议这么做的
    在这里插入图片描述

如果实在需要在循环外访问循环内的临时变量,可以在循环外预先定义(一般不要这样做,因为i变量的取值如下图所示,并不能改变多少)

如图,每一次循环的时候,都会将取出的值赋予i变量。

  • 由于i变量是在循环之前(外)定义的
  • 在循环外访问i变量是合理的、允许的

在这里插入图片描述

4.for循环的嵌套应用

"""
演示嵌套应用for循环
"""

# 坚持表白100天,每天都送10朵花
# range
i = 0
for i in range(1, 101):
    print(f"今天是向小美表白的第{i}天,加油坚持。")

    # 写内层的循环了
    for j in range(1, 11):
        print(f"给小美送的第{j}朵玫瑰花")

    print("小美我喜欢你")

print(f"第{i}天,表白成功")

5.循环中断:break ,continue

continue

  • 暂时跳过某次循环,直接进行下一次

break

  • 提前退出循环,不再继续
  1. continue和break,在for和while循环中作用一致

  2. 在嵌套循环中,只能作用在所在的循环上,无法对上层循环起作用

#每天送5朵花,送10天
i = 1
j = 1
while i<=10:
    print(f"今天是送花的第{i}天")
    i+=1
    while j<=5:
        print(f"这是送的第{j}朵花")
        j+=1
        if j==3:
            break #如果是break,到达3之后,后面全部跳过
                  #如果是continue,只会在等于3的时候跳,后面的照样执行

第四章 函数

1.函数介绍

函数:是组织好的,可重复使用的,用来实现特定功能的代码段。

我们使用过的:input()、print()、str()、int()等都是Python的内置函数

请添加图片描述

提问: 为什么随时都可以使用len()统计长度?

因为,len()是Python内置的函数:

  • 是提前写好的
  • 可以重复使用
  • 实现统计长度这一特定功能的代码段

使用函数的好处是:

  • 将功能封装在函数内,可供随时随地重复利用
  • 提高代码的复用性,减少重复代码,提高开发效率

2.函数定义

#函数的定义
def 函数名(传入参数):
	函数体
	return 返回值
#函数调用
函数名(传入参数)

① 参数如不需要,可以省略(后续章节讲解)
② 返回值如不需要,可以省略(后续章节讲解)
③ 函数必须先定义后调用

"""
演示函数基础定义练习案例:自动查核酸
"""

# 定义函数
def check():
    # 编写函数体输出信息
    print("请出示您的健康码以及72小时核酸证明!")

# 调用函数
check()

3.函数参数

传入参数的功能是:在函数进行计算的时候,接受外部(调用时)提供的数据
在这里插入图片描述
在这里插入图片描述

"""
演示函数使用参数
"""

# 定义2数相加的函数,通过参数接收被计算的3个数字
def add(x, y, z):
    result = x + y + z
    print(f"{x} + {y} + {z}的计算结果是:{result}")

# 调用函数,传入被计算的3个数字
add(5, 6, 7)

函数定义中,提供的x,y和z,称之为:形式参数(形参),表示函数声明将要使用2个参数

  • 参数之间使用逗号进行分隔

函数调用中,提供的5,6和7,称之为:实际参数(实参),表示函数执行时真正使用的参数值

  • 传入的时候,按照顺序传入数据,使用逗号分隔

总结

  1. 函数定义中的参数,称之为形式参数
  2. 函数调用中的参数,称之为实际参数
  3. 函数的参数数量不限(也可以没有),使用逗号分隔开
  4. 传入参数的时候,要和形式参数一一对应,逗号隔开

4.函数返回值

所谓“返回值”,就是程序中函数完成事情后,最后给调用者的结果

函数体在遇到return后就结束了,所以写在return后的代码不会执行。

语法就是:通过return关键字,就能向调用者返回数据

def 函数(参数)
	函数体
    return 返回值
变量 = 函数(参数)
"""
改用上面的代码
"""

# 定义2数相加的函数,通过参数接收被计算的3个数字
def add(x, y, z):
    result = x + y + z
    return result


# 调用函数,传入被计算的3个数字
b = add(5, 6, 7)
print(b)

None类型

思考:如果函数没有使用return语句返回数据,那么函数有返回值吗?

实际上是:有的。

Python中有一个特殊的字面量:None,其类型是:<class ‘NoneType’>
无返回值的函数,实际上就是返回了:None这个字面量

None表示:空的、无实际意义的意思
函数返回的None,就表示,这个函数没有返回什么有意义的内容。
也就是返回了空的意思。

def say_hello():
	print("hello...")
#   return None  None可以主动使用return返回,效果等同于不写return语句:  
#使用变量接收这个函数的返回值
result = say_hello()	
#打印返回值
print(result)		#结果None
#打印返回值类型
print(type(result)) #结果<class 'NoneType'>

None类型应用场景

None作为一个特殊的字面量,用于表示:空、无意义,其有非常多的应用场景。

  • 用在函数无返回值上
  • 用在if判断上
    在if判断中,None等同于False
    一般用于在函数中主动返回None,配合if判断做相关处理

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 用于声明无内容的变量上
    定义变量,但暂时不需要变量有具体值,可以用None来代替
#暂不赋予变量具体值
name = None

5.函数说明文档

函数是纯代码语言,想要理解其含义,就需要一行行的去阅读理解代码,效率比较低。
我们可以给函数添加说明文档,辅助理解函数的作用。

其实就是给函数写个注释,说明一下这个函数是干啥的

语法如下:

def add(x,y):
    """
    函数说明
    :param x: 形参x的说明
    :param y: 形参y的说明
    :return:  返回值的说明
    """
	函数体
    return 返回值

通过多行注释的形式,对函数进行说明解释,内容应写在函数体之前

param 用于解释参数
return 用于解释返回值

在PyCharm编写代码时,可以通过鼠标悬停,查看调用函数的说明文档

6.函数嵌套调用

所谓函数嵌套调用指的是一个函数里面又调用了另外一个函数。

如下效果:

如果函数A中,调用了另外一个函数B,那么先把函数B中的任务都执行完毕之后才会回到上次 函数A执行的位置

7.变量作用域

变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用)
主要分为两类:局部变量和全局变量

1.局部变量

所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效

变量a是定义在testA函数内部的变量,在函数外部访问则立即报错。

局部变量的作用:在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量

2.全局变量

所谓全局变量,指的是在函数体内、外都能生效的变量
思考:如果有一个数据,在函数A和函数B中都要使用,该怎么办?
答:将这个数据存储在一个全局变量里面

global关键字

使用 global关键字 可以在函数内部声明变量为全局变量, 如下所示:

综合小练习

  • 定义一个全局变量:money,用来记录银行卡余额(默认5000000)

  • 定义一个全局变量:name,用来记录客户姓名(启动程序时输入)
    定义如下的函数:

  • 查询余额函数

  • 存款函数

  • 取款函数

  • 主菜单函数
    要求:

  • 程序启动后要求输入客户姓名

  • 查询余额、存款、取款后都会返回主菜单

  • 存款、取款后,都应显示一下当前余额

  • 客户选择退出或输入错误,程序会退出,否则一直运行

"""
演示函数综合案例开发
"""

# 定义全局变量money name
money = 5000000
name = None
# 要求客户输入姓名
name = input("请输入您的姓名:")
# 定义查询函数
def query(show_header):
    if show_header:
        print("-------------查询余额------------")
    print(f"{name},您好,您的余额剩余:{money}元")


# 定义存款函数
def saving(num):
    global money    # money在函数内部定义为全局变量
    money += num
    print("-------------存款------------")
    print(f"{name},您好,您存款{num}元成功。")

    # 调用query函数查询余额
    query(False)

# 定义取款函数
def get_money(num):
    global money
    money -= num
    print("-------------取款------------")
    print(f"{name},您好,您取款{num}元成功。")

    # 调用query函数查询余额
    query(False)
# 定义主菜单函数
def main():
    print("-------------主菜单------------")
    print(f"{name},您好,欢迎来到银行ATM。请选择操作:")
    print("查询余额\t[输入1]")
    print("存款\t\t[输入2]")
    print("取款\t\t[输入3]")    # 通过\t制表符对齐输出
    print("退出\t\t[输入4]")
    return input("请输入您的选择:")

# 设置无限循环,确保程序不退出
while True:
    keyboard_input = main()
    if keyboard_input == "1":
        query(True)
        continue    # 通过continue继续下一次循环,一进来就是回到了主菜单
    elif keyboard_input == "2":
        num = int(input("您想要存多少钱?请输入:"))
        saving(num)
        continue
    elif keyboard_input == "3":
        num = int(input("您想要取多少钱?请输入:"))
        get_money(num)
        continue
    else:
        print("程序退出啦")
        break       # 通过break退出循环

第五章函数进阶

1.函数的多返回值

如果一个函数要有多个返回值,该如何书写代码?

def test_return():
    return 1,2
x,y = test_return()	#按照返回值的顺序,写对应顺序的多个变量接收即可
print(x)		#变量之间用逗号隔开,支持不同类型的数据return
print(y)

2.函数的多种传参方式

使用方式上的不同, 函数有4中常见参数使用方式:

  • 位置参数(根据参数位置来传递参数)
  • 关键字参数(通过“键=值”形式传递参数,可以不限参数顺序 ,可以和位置参数混用,位置参数需在前)
  • 缺省参数(不传递参数值时会使用默认的参数值 默认值的参数必须定义在最后)
  • 不定长参数( 位置不定长传递以*号标记一个形式参数,以元组的形式接受参数,形式参数一般命名为args 关键字不定长传递以**号标记一个形式参数,以字典的形式接受参数,形式参数一般命名为kwargs)

位置参数

位置参数:调用函数时根据函数定义的参数位置来传递参数

def user_info(name,age,gender)
	print(f'您的名字是{name},年龄是{age},性别是{gender}')
    
user_info('TOM',20,'男')

注意: 传递的参数和定义的参数的顺序及个数必须一致

关键字参数

关键字参数:函数调用时通过“键=值”形式传递参数.作用: 可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求。

def user_info(name,age,gender):
	print(f'您的名字是{name},年龄是{age},性别是{gender}')
   
#关键字传参
user_info(name ='TOM',age = 20,gender = '男')
#可以不按照固定顺序
user_info(age = 20,name ='TOM',gender = '男')
#可以和位置参数混用,位置参数必须在前,且匹配参数顺序
user_info("小明",age = 20,gender = '男')      #一般不要这样用

注意:函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序

不定长参数

不定长参数:不定长参数也叫可变参数. 用于不确定调用的时候会传递多少个参数(不传参也可以)的场景.

作用: 当调用函数时不确定参数个数时, 可以使用不定长参数

不定长参数的类型: ①位置传递 ②关键字传递

def user_info(*args): #args是固定的拼写,不可以自定义
	print(args)
#('TOM')
user_info('TOM')
#('TOM',18)
user_info('TOM',18)

注意:传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递

缺省参数

缺省参数:缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)。

作用: 当调用函数时没有传递参数, 就会使用默认是用缺省参数对应的值.

def user_info(name,age,gender='男'): #为参数提供默认值,调用函数时可不传该默认参数的值
	print(f'您的名字是{name},年龄是{age},性别是{gender}')

user_info('TOM',20)

user_info('TOM',18,'女')

关键字传递

注意: 参数是“键=值”形式的形式的情况下, 所有的“键=值”都会被kwargs接受, 同时会根据“键=值”组成字典.

def user_info(**kwargs): #kwargs是固定的拼写,不可以自定义
	print(kwargs)

#('name':TOM','age':18,'id':110)
user_info(name:TOM',age:18,id:110)

3.匿名函数

1.函数作为参数传递

在前面的函数学习中,我们一直使用的函数,都是接受数据作为参数传入:

  • 数字
  • 字符串
  • 字典、列表、元组等

其实,我们学习的函数本身,也可以作为参数传入另一个函数内。

def test_func(compute):
    result = compute(1,2)
    print(result)
def compute(x,y):
    return x+y
test_func(compute)	#结果:3

函数compute,作为参数,传入了test_func函数中使用。

  • test_func需要一个函数作为参数传入,这个函数需要接收2个数字进行计算,计算逻辑由这个被传入函数决定

  • compute函数接收2个数字对其进行计算,compute函数作为参数,传递给了test_func函数使用

  • 最终,在test_func函数内部,由传入的compute函数,完成了对数字的计算操作

所以,这是一种,计算逻辑的传递,而非数据的传递。

就像上述代码那样,不仅仅是相加,相减、相除、等任何逻辑都可以自行定义并作为函数传入。

1.函数本身是可以作为参数,传入另一个函数中进行使用的。2. 将函数传入的作用在于:传入计算逻辑,而非传入数据。

2.lambda匿名函数

函数的定义中

  1. def关键字可以定义带有名称的函数

  2. lambda关键字,可以定义匿名函数(无名称)

  • 有名称的函数,可以基于名称重复使用。
  • 无名称的匿名函数,只可临时使用一次。

匿名函数定义语法:

lambda 传入参数:函数体(一行代码)
  • lambda 是关键字,表示定义匿名函数
  • 传入参数表示匿名函数的形式参数,如:x, y 表示接收2个形式参数
  • 函数体,就是函数的执行逻辑,要注意:只能写一行,无法写多行代码
  1. 通过def关键字,定义一个函数,并传入,如下图:
def test_func(computer):
    result = computer(1,2)
    print(result)
def computer(x,y):
    return x+y
test_func(computer)
#结果:3
  1. 也可以通过lambda关键字,传入一个一次性使用的lambda匿名函数
def test_func(computer):
    result = computer(1,2)
    print(result)
test_func(lambda x,y:x+y)
#结果:3

使用def和使用lambda,定义的函数功能完全一致,只是lambda关键字定义的函数是匿名的,无法二次使用

注意事项:

  • 匿名函数用于临时构建一个函数,只用一次的场景匿名
  • 函数的定义中,函数体只能写一行代码,如果函数体要写多行代码,不可用lambda匿名函数,应使用def定义带名函数

第六章数据容器

1.初识数据容器

学习数据容器,就是为了批量存储或批量使用多份数据

思考一个问题:如果我想要在程序中,记录5名学生的信息,如姓名。
如何做呢?

  1. 定义五个变量(不高级且低效)
name1 ='王丽红'
name2 ='周杰轮'
name3 ='林俊姐'
name4 ='张学油'
name5 ='刘德滑'
  1. 一个变量完成(优雅、高效,这就是数据容器,一个容器可以容纳多份数据)

    #一个变量存多份数据,优雅实在是优雅
    name_list = ['王丽红','周杰轮','林俊姐','张学油','刘德滑']
    print(name_list)
    

注意用中括号表示,跟C语言的数组很像

Python中的数据容器:
一种可以容纳多份数据的数据类型,容纳的每一份数据称之为1个元素
每一个元素,可以是任意类型的数据,如字符串、数字、布尔等。

数据容器根据特点的不同,如:

  • 是否支持重复元素

  • 是否可以修改

  • 是否有序,等

    分为5类,分别是:
    列表(list)、元组(tuple)、字符串(str)、集合(set)、字典(dict)

2.数据容器:list(列表)

1.列表的定义

基本语法:

#字面量
[元素1,元素2,元素3....]

#定义变量
变量的名称 = [元素1,元素2,元素3....]

#定义空变量
变量的名称 = []
变量的名称 = list()

列表内的每一个数据,称之为元素

  • 以 [ ] 作为标识
  • 列表内每一个元素之间用, 逗号隔开

元素的数据类型没有任何限制,甚至元素也可以是列表,这样就定义了嵌套列表

在这里插入图片描述

2.列表的下标索引

跟C语言的数组很像哦!!! 列表[下标],即可取出

在这里插入图片描述

  1. 列表中的每一个元素,都有其位置下标索引,从前向后的方向,从0开始,依次递增
    我们只需要按照下标索引,即可取得对应位置的元素。

在这里插入图片描述

  1. 或者,可以反向索引,也就是从后向前:从-1开始,依次递减(-1、-2、-3…)

一般不这样用,正向的就很好

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这里插入图片描述

  1. 如果列表是嵌套的列表,同样支持下标索引(二维数组哈哈哈哈)

在这里插入图片描述

在这里插入图片描述

要注意下标索引的取值范围,超出范围无法取出元素,并且会报错

3.列表的常用操作(增删改查)

列表除了可以:

  • 定义
  • 使用下标索引获取值

以外,列表也提供了一系列功能:

  • 插入元素
  • 删除元素
  • 清空列表
  • 修改元素
  • 统计元素个数
    等等功能,这些功能我们都称之为:列表的方法

3.1列表的查询功能

跟C语言的结构体很像很像,通过 . 来引出方法里面的函数

回忆:函数是一个封装的代码单元,可以提供特定功能。

在Python中,如果将函数定义为class(类)的成员,那么函数会称之为:方法

#函数
def add(x,y)
	return x+y
#方法
class Student
	def add(self,x,y)
    	return x+y
    
#方法和函数功能一样, 有传入参数,有返回值,只是方法的使用格式不同:
1.函数的使用
num = add(1,2)

2.方法的使用
student = Student()
num =student.add(1,2)

查找某元素的下标

  • 功能:查找指定元素在列表的下标,如果找不到,报错ValueError

  • 语法:列表.index(元素)

    index就是列表对象(变量)内置的方法(函数)

    my_list = ["a","b","c"]
    print(my_list.index("b"))	#结果:1
    

3.2列表的修改功能(方法):

修改特定位置(索引)的元素值:

一句话,直接改就行了

  • 语法:列表[下标] = 值
  • 可以使用如上语法,直接对指定下标(正向、反向下标均可)的值进行:重新赋值(修改)
#正向下标
my_list = [1,2,3]
my_list[0] = 5
print(my_list)	#结果:[5,2,3]

#反向下标
my_list = [1,2,3]
my_list[-3] = 5
print(my_list)	#结果:[5,2,3]
插入元素:

insert()

语法:列表.insert(下标, 元素),在指定的下标位置,插入指定的元素

my_list = [5,6,7]
my_list.insert(2,"A")
print(my_list)	#结果:[5,6,"A",7]

插入的元素代替原先元素的位置,原先的元素向后移

追加元素:

函数一:append()

语法:列表.append(元素),将指定元素,追加到列表的尾部

my_list = [4,6,5]
my_list.append(4)	 
print(my_list)	#结果:[4,5,4,4]	

my_list = [4,6,5]
my_list.append([5,5,5])	 
print(my_list)	#结果:[4,5,4,[5,5,5]]	

函数二:extend()

语法:列表.extend(其它数据容器),将其它数据容器的内容取出,依次追加到列表尾部

my_list = [4,6,5]
my_list.extend([5,5,5])	 
print(my_list)	#结果:[4,5,4,5,5,5]	
删除元素
  • 语法1: del 列表[下标]
  • 语法2:列表.pop(下标)
my_list = [4,6,5]

#方式一
del my_list[1]
print(my_list)	#结果:[4,5]
#方式二
my_list.pop(1)
print(my_list)	#结果:[4,5]

删除某元素在列表中的第一个匹配项

语法:列表.remove(元素)

my_list = [4,6,5,5,3]
my_list.remove(5)
print(my_list)	#结果:[4,6,5,3]

清空列表内容

语法:列表.clear()

my_list = [4,6,5,5,3]
my_list.clear()
print(my_list)	#结果:[]

统计某元素在列表内的数量

语法:列表.count(元素)

my_list = [4,6,5,5,3]
print(my_list.count(5))	#结果:2

统计列表内,有多少元素
语法:len(列表)

可以得到一个int数字,表示列表内的元素数量

my_list = [4,6,5,"efs",3]
print(len(my_list))	#结果:5

总览

编号使用方式作用
1列表.append(元素)向列表中追加一个元素
2列表.extend(容器)将数据容器的内容依次取出,追加到列表尾部
3列表.insert(下标, 元素)在指定下标处,插入指定的元素
4del 列表[下标]删除列表指定下标元素
5列表.pop(下标)删除列表指定下标元素
6列表.remove(元素)从前向后,删除此元素第一个匹配项
7列表.clear()清空列表
8列表.count(元素)统计此元素在列表中出现的次数
9列表.index(元素)查找指定元素在列表的下标找不到报错ValueError
10len(列表)统计容器内有多少元素

学习编程,不仅仅是Python语言本身,以后根据方向,会学习更多的框架技术。
除了经常用的,大多数是记忆不下来的。

经过上述对列表的学习,可以总结出列表有如下特点:

  • 可以容纳多个元素(上限为2**63-1、9223372036854775807个)
  • 可以容纳不同类型的元素(混装)
  • 数据是有序存储的(有下标序号)
  • 允许重复数据存在
  • 可以修改(增加或删除元素等)

综合练习

有一个列表,内容是:[21, 25, 21, 23, 22, 20],记录的是一批学生的年龄

请通过列表的功能(方法),对其进行

1.定义这个列表,并用变量接收它

2.追加一个数字31,到列表的尾部

3.追加一个新列表[29, 33, 30],到列表的尾部

4.取出第一个元素(应是:21)

5.取出最后一个元素(应是:30)

6.查找元素31,在列表中的下标位置

#1.定义这个列表,并用变量接收它
age = [21, 25, 21, 23, 22, 20]
#2.追加一个数字31,到列表的尾部
age.append(31)
#3.追加一个新列表[29, 33, 30],到列表的尾部
age.extend([29,33,30])
#4.取出第一个元素(应是:21)
first = age[0]
#5.取出最后一个元素(应是:30)
first = age[-1]
#6.查找元素31,在列表中的下标位置
print(age.index(31))

4.list(列表)的遍历

while循环

既然数据容器可以存储多个元素,那么,就会有需求从容器内依次取出元素进行操作。

将容器内的元素依次取出进行处理的行为,称之为:遍历、迭代。

a = 0
while a<len[列表]:
	路人甲 = 列表[a]
    对路人甲进行处理
    a+=1

for循环

for 临时变量 in 数据容器
	对临时变量进行处理
    
示例代码:
my_list = [1,2,3]
for i in my_list:
	print(i)
    
结果:
1
2
3
whliefor
在循环控制上while循环可以自定循环条件,并自行控制for循环不可以自定循环条件,只可以一个个从容器内取出数据
在无限循环上while循环可以通过条件控制做到无限循环for循环理论上不可以,因为被遍历的容器容量不是无限的
在使用场景上while循环适用于任何想要循环的场景for循环适用于,遍历数据容器的场景或简单的固定次数循环场景

练习案例

定义一个列表,内容是:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

  • 遍历列表,取出列表内的偶数,并存入一个新的列表对象中
  • 使用while循环和for循环各操作一次
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = []
a = 0
while a < len(list1):
    if list1[a] % 2 == 0:
        list2.append(list1[a])
    a += 1
print(list2)
结果:
[2, 4, 6, 8, 10]
list1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
list2 = []
for a in list1:
    if a%2==0:
        list2.append(a)
print(list2)
结果:
[2, 4, 6, 8, 10]

3.数据容器:tuple(元组)

1.元组的定义

思考:列表是可以修改的。如果想要传递的信息,不被篡改,列表就不合适了。

元组同列表一样,都是可以封装多个、不同类型的元素在内。

但最大的不同点在于:元组一旦定义完成,就不可修改

所以,当我们需要在程序内封装数据,又不希望封装的数据被篡改,那么元组就非常合适了

元组定义:定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。

#定义元组字面量
(元素,元素,元素.....)
# 定义元组变量
变量名称 = (元素,元素,元素.....)
#定义空元组
变量名称 =()        #方式1
变量名称 =tuple()	#方式2
#定义3个元素的元组
t1 = (1,"hello",True)
#定义1个元素的元组
t2 = ('hello',)	#注意:必须带有逗号,否则不是元组类型
#元组也支持嵌套
t1 =((1,2,3)(4,5,6))
print(t1[0][0])	#结果:1

2.元组的操作

元组由于不可修改的特性,所以其操作方法非常少

编号方法作用
1index()查找某个数据,如果数据存在返回对应的下标,否则报错
2count()统计某个数据在当前元组出现的次数
3len(元组)统计元组内的元素个数
#根据下标(索引)取出数据
t1 = (1,2,'hello')
print(t1[2])	#结果:'hello'

#根据index(),查找特定元素的第一个匹配项
t1 = (1,2,'hello',3,4,'hello')
print(t1.index('hello'))	#结果:2

#统计某个数据在元组内出现的次数
t1 = (1,2,'hello',3,4,'hello')
print(t1.conunt('hello'))	#结果:2

#统计元组内的元素个数
t1 = (1,2,3)
print(len(t1))				#结果:3

注意

  1. 不可以修改元组的内容,否则会直接报错
  2. 可以修改元组内的list的内容(修改元素、增加、删除、反转等)
t1 = (1,2,['A','B'])
  1. 不可以替换list为其它list或其它类型

元组的遍历

#while循环
t1 =(5,6,8)
a = 0
while a<len(t1):
    print(t1[a])
    a+=1
运行结果:
5,6,8
t1 =(5,6,8)
for a in t1:
    print(a)
运行结果:
5,6,8

3.元组的特点

经过上述对元组的学习,可以总结出列表有如下特点:

  • 可以容纳多个数据

  • 可以容纳不同类型的数据(混装)

  • 数据是有序存储的(下标索引)

  • 允许重复数据存在

  • 不可以修改(增加或删除元素等)

  • 支持for循环

    多数特性和list一致,不同点在于不可修改的特性。

练习案例

定义一个元组,内容是:(‘周杰轮’, 11, [‘football’, ‘music’]),记录的是一个学生的信息(姓名、年龄、爱好)

请通过元组的功能(方法),对其进行

  1. 查询其年龄所在的下标位置
  2. 查询学生的姓名
  3. 删除学生爱好中的football
  4. 增加爱好:coding到爱好list内
t1 = ('周杰轮', 11, ['football', 'music'])

4.数据容器:str(字符串)

字符串是字符的容器,一个字符串可以存放任意数量的字符。

1.字符串的下标(索引)

和其它容器如:列表、元组一样,字符串也可以通过下标进行访问

  • 从前向后,下标从0开始
  • 从后向前,下标从-1开始

同元组一样,字符串是一个:无法修改的数据容器。

如果必须要做,只能得到一个新的字符串,旧的字符串是无法修改

#通过下标获取特定位置字符
str1 = "hello world"
print(str[0])	#结果:h
print(str[-1])	#结果:d

2.字符串的常用操作

1.查找特定字符串的下标索引值

语法:字符串.index(字符串)

str1 = "hello world"
print(str1.index("wo"))	#结果:6  注意空格也算一个字符

2.字符串的替换

语法:字符串.replace(字符串1,字符串2)

功能:将字符串内的全部:字符串1,替换为字符串2

注意:不是修改字符串本身,而是得到了一个新字符串哦

str1 = "hello world"
str2 = str1.replace("wo","you")

print(str1)	#结果 :hello world
print(str2)	#结果: hello yourld

可以看到,字符串name本身并没有发生变化 而是得到了一个新字符串对象

3.字符串的分割

语法:字符串.split(分隔符字符串)

功能:按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中

注意:字符串本身不变,而是得到了一个列表对象

str1 = "hello everyone hello world"
list1 = str1.split(" ")
print(list1)
print(type(list1))

#结果:
['hello', 'everyone', 'hello', 'world']
<class 'list'>

可以看到,字符串按照给定的 <空格>进行了分割,变成多个子字符串,并存入一个列表对象中。

4.字符串的规整操作

注意字符串不能被修改,只是得到了一个新字符串

  • 去前后空格

语法:字符串.strip()

str1 = " hello everyone hello world "
list1 = str1.strip()
print(list1)
print(str1)
#结果:
hello everyone hello world
 hello everyone hello world 
  • 去前后指定字符串

语法:字符串.strip(字符串)

str1 = "112hello everyone hello world212"
list1 = str1.strip("12")
print(list1)
print(str1)
#结果:
hello everyone hello world
112hello everyone hello world212

注意,传入的是“12” 其实就是:”1”和”2”都会移除,是按照单个字符。

5.统计字符串中某字符串的出现次数

语法:字符串.count(字符串)

str1 = "112hello everyone hello world212"
list1 = str1.count("21")
print(list1)
print(str1)
#结果:
1
112hello everyone hello world212

6.统计字符串的长度

语法:len(字符串)

str1 = "12 ab !@#$ 你好"
print(len(str1))

可以看出:

  • 数字(1、2、3…)
  • 字母(abcd、ABCD等)
  • 符号(空格、!、@、#、$等)
  • 中文

均算作1个字符

字符串常用操作汇总

编号操作说明
1字符串[下标]根据下标索引取出特定位置字符
2字符串.index(字符串)查找给定字符的第一个匹配项的下标
3字符串.replace(字符串1, 字符串2)将字符串内的全部字符串1,替换为字符串2不会修改原字符串,而是得到一个新的
4字符串.split(字符串)按照给定字符串,对字符串进行分隔不会修改原字符串,而是得到一个新的列表
5字符串.strip()字符串.strip(字符串)移除首尾的空格和换行符或指定字符串
6字符串.count(字符串)统计字符串内某字符串的出现次数
7len(字符串)统计字符串的字符个数

5.数据容器(序列)的切片

序列是指:内容连续、有序,可使用下标索引的一类数据容器

列表、元组、字符串,均可以可以视为序列。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这里插入图片描述

序列支持切片,即:列表、元组、字符串,均支持进行切片操作

切片:从一个序列中,取出一个子序列

语法:序列[起始下标:结束下标:步长]

表示从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列:

  1. 起始下标表示从何处开始 【可以留空,留空视作从头开始】
  2. 结束下标(不含)表示何处结束 【可以留空,留空视作截取到结尾】
  3. 步长表示,依次取元素的间隔

步长1表示,一个个取元素

步长2表示,每次跳过1个元素取

步长N表示,每次跳过N-1个元素取

步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)

注意,此操作不会影响序列本身,而是会得到一个新的序列(列表、元组、字符串)

示例代码:

my_list = [1, 2, 3, 4, 5]
new_list = my_list[1:4]	# 下标1开始,下标4(不含)结束,步长1
print(new_list)		# 结果:[2, 3, 4]

my_tuple = (1, 2, 3, 4, 5)
new_tuple = my_tuple[:]	# 从头开始,到最后结束,步长1
print(new_tuple)		# 结果:(1, 2, 3, 4, 5)

my_list = [1, 2, 3, 4, 5]
new_list = my_list[::2]		# 从头开始,到最后结束,步长2
print(new_list)		# 结果:[1, 3, 5]

my_str = "12345"
new_str = my_str[:4:2]	# 从头开始,到下标4(不含)结束,步长2
print(new_str)		# 结果:"13"

my_str = "12345"
new_str = my_str[::-1]	# 从头(最后)开始,到尾结束,步长-1(倒序)
print(new_str)		# 结果:"54321"

my_list = [1, 2, 3, 4, 5]
new_list = my_list[3:1:-1]	# 从下标3开始,到下标1(不含)结束,步长-1(倒序)
print(new_list)		# 结果:[4, 3]

my_tuple = (1, 2, 3, 4, 5)
new_tuple = my_tuple[:1:-2] 	# 从头(最后)开始,到下标1(不含)结束,步长-2(倒序)
print(new_tuple)		# 结果:(5, 3)

可以看到,这个操作对列表、元组、字符串是通用的

同时非常灵活,根据需求,起始位置,结束位置,步长(正反序)都是可以自行控制的

6.数据容器:set(集合)

1.集合的特点

可以理解为数学中的集合,概念

  1. 确定性:集合中的元素都是确定的。
  2. 互异性:集合中的元素都是不同的。
  3. 无序性:集合中的元素没有特定的顺序

我们目前接触到了列表、元组、字符串三个数据容器了。基本满足大多数的使用场景。为何又需要学习新的集合类型呢?

通过特性来分析:列表可修改、支持重复元素且有序, 元组、字符串不可修改、支持重复元素且有序

有没有看出一些局限?

局限就在于:它们都支持重复元素。如果场景需要对内容做去重处理,列表、元组、字符串就不方便了。

而集合,最主要的特点就是:不支持元素的重复(自带去重功能)、并且内容无序

和列表、元组、字符串等定义基本相同:

  • 列表使用:[]
  • 元组使用:()
  • 字符串使用:“”
  • 集合使用:{}

集合有如下特点:

  1. 可以容纳多个数据
  2. 可以容纳不同类型的数据(混装)
  3. 数据是无序存储的(不支持下标索引)
  4. 不允许重复数据存在
  5. 可以修改(增加或删除元素等)
  6. 支持for循环

2.集合的定义

基本语法:

#定义集合字面量
{元素,元素,......}
#定义集合变量
变量名称 = {元素,元素,......}
#定义空集合
变量名称 = set()
set1 = {1,2,3,4,1,1,2,3,5}
print(set1)
#结果
{1, 2, 3, 4, 5}

3.集合的常见操作

首先,因为集合是无序的,所以集合不支持:下标索引访问

但是集合和列表一样,是允许修改的,所以我们来看看集合的修改方法

  1. 添加新元素

    语法:集合.add(元素)。将指定元素,添加到集合内

    结果:集合本身被修改,添加了新元素

    set1 = {1,2}
    set1.add(3)
    print(set1)	#结果:{1,2,3}
    #注意:一次只能添加一个新元素
    
  2. 移除元素

​ 语法:集合.remove(元素),将指定元素,从集合内移除

​ 结果:集合本身被修改,移除了元素

set1 = {1,2,3}
set1.remove(3)
print(set1)	#结果:{1,2}
  1. 从集合中随机取出元素

​ 语法:集合.pop(),功能,从集合中随机取出一个元素

​ 结果:会得到一个元素的结果。同时集合本身被修改,元素被移除

set1 = {1,2,3}
set2 = set1.pop()
print(set1)		#结果:{2, 3}
print(set2)		#结果:1
  1. 清空集合

    语法:集合.clear(),功能,清空集合

    结果:集合本身被清空

set1 = {1,2,3}
set1.clear()
print(set1)	#结果:set()  空集合
  1. 取出2个集合的差集

    语法:集合1.difference(集合2),

    功能:取出集合1和集合2的差集(集合1有而集合2没有的)

    结果:得到一个新集合,集合1和集合2不变

set1 = {1,2,3}
set2 = {1,5,6}
set3 = set1.difference(set2)
print(set1)
print(set2)
print(set3)
#结果:
{1, 2, 3}
{1, 5, 6}
{2, 3}
  1. 消除2个集合的差集

    语法:集合1.difference_update(集合2)

    功能:对比集合1和集合2,在集合1内,删除和集合2相同的元素。

    结果:集合1被修改,集合2不变

set1 = {1,2,3}
set2 = {1,5,6}
set1.difference_update(set2)

print(set1)
print(set2)
#结果:
{2, 3}
{1, 5, 6}
  1. 2个集合合并

    语法:集合1.union(集合2)

    功能:将集合1和集合2组合成新集合

    结果:得到新集合,集合1和集合2不变

set1 = {1,2,3}
set2 = {1,5,6}
set3 = set1.union(set2)

print(set3)	#结果:{1, 2, 3, 5, 6}
print(set1) #结果:{1, 2, 3}
print(set2) #结果:{1, 5, 6}
  1. 查看集合的元素数量

    语法:len(集合)

    功能:统计集合内有多少元素

    结果:得到一个整数结果

set1 = {1,2,3}
print(len(set1))	#结果:3
  1. for循环遍历

    要注意:集合不支持下标索引,所以也就不支持使用while循环。

set1 = {1,2,3}
for i in set1:
    print(i)
#结果:
1
2
3

集合常用功能总结

编号操作说明
1集合.add(元素)集合内添加一个元素
2集合.remove(元素)移除集合内指定的元素
3集合.pop()从集合中随机取出一个元素
4集合.clear()将集合清空
5集合1.difference(集合2)得到一个新集合,内含2个集合的差集原有的2个集合内容不变
6集合1.difference_update(集合2)在集合1中,删除集合2中存在的元素集合1被修改,集合2不变
7集合1.union(集合2)得到1个新集合,内含2个集合的全部元素原有的2个集合内容不变
8len(集合)得到一个整数,记录了集合的元素数量

综合练习

有如下列表对象:my_list = [1, 2,1,2,”A”,”B”,”A”]

请:

  • 定义一个空集合
  • 通过for循环遍历列表
  • 在for循环中将列表的元素添加至集合
  • 最终得到元素去重后的集合对象,并打印输出
my_list = [1, 2, 1, 2, "A", "B", "A"]
set1 = set()
for i in my_list:
    set1.add(i)
print(set1)
#结果:
{1, 2, 'A', 'B'}

7.数据容器:dict(字典、映射)

1.字典的含义

生活中的字典:在这里插入图片描述

通过【字】 ,就能找到对应的【含义】。

所以,我们可以认为,生活中的字典就是记录的一堆:【字】:【含义】【字】:【含义】…【字】:【含义】

在这里插入图片描述

Python中字典和生活中字典十分相像:

生活中的字典Python中的字典
【字】:【含义】Key: Value

老师有一份名单,记录了学生的姓名和考试总成绩。在这里插入图片描述

现在需要将其通过Python录入至程序中,并可以通过学生姓名检索学生的成绩。

使用字典最为合适:在这里插入图片描述

可以通过Key(学生姓名),取到对应的Value(考试成绩)。

所以,为什么使用字典? 因为可以使用字典,实现用key取出Value的操作

2.字典的定义

字典的定义,同样使用{},不过存储的元素是一个个的:键值对,如下语法:

#定义字典字面量
{key:value,key:value,......}
#定义字典变量
mydict = {key:value,key:value,......}
#定义空字典
mydict ={}			#空字典定义方式1
mydict = dict()		#空字典定义方式2
  1. 使用{}存储原始,每一个元素是一个键值对
  2. 每一个键值对包含Key和Value(用冒号分隔)
  3. 键值对之间使用逗号分隔
  4. Key和Value可以是任意类型的数据(key不可为字典)
  5. Key不可重复,重复会对原有数据覆盖

前文中记录学生成绩的需求,可以如下记录:

stu_score ={"王力鸿":99,"周杰轮":88,"林俊接":77}

1.字典同集合一样,不可以使用下标索引,但是字典可以通过Key值来取得对应的Value

#语法,字典[key]可以取到对应的Value
stu_score ={"王力鸿":99,"周杰轮":88,"林俊接":77}
print(stu_score["王力鸿"]) #结果:99
print(stu_score["周杰轮"]) #结果:88
print(stu_score["林俊接"]) #结果:77

2.字典的Key和Value可以是任意数据类型(Key不可为字典)

那么,就表明,字典是可以嵌套的。

需求如下:记录学生各科的考试信息
在这里插入图片描述

stu_score ={
    "王力鸿":{"语文":77,"数学":66,"英语":33},
    "周杰轮":{"语文":88,"数学":86,"英语":55},
    "林俊接":{"语文":99,"数学":96,"英语":66}}

嵌套字典的内容获取,如下所示:

stu_score ={
    "王力鸿":{"语文":77,"数学":66,"英语":33},
    "周杰轮":{"语文":88,"数学":86,"英语":55},
    "林俊接":{"语文":99,"数学":96,"英语":66}}
print(stu_score["王力鸿"])			  #结果:{'语文': 77, '数学': 66, '英语': 33}
print(stu_score["王力鸿"]["语文"])   #结果:77
print(stu_score["周杰轮"]["英语"])   #结果:55

3.字典的常用操作

  1. 新增元素

    语法:字典[Key] = Value,结果:字典被修改,新增了元素

stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}
#新增,张学油的考试成绩
stu_score['张学油'] = 66
print(stu_score) 
#结果:{'王力鸿': 99, '周杰轮': 88, '林俊接': 77, '张学油': 66}
  1. 更新元素

    语法:字典[Key] = Value,结果:字典被修改,元素被更新

    注意:字典Key不可以重复,所以对已存在的Key执行上述操作,就是更新Value值

stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}

stu_score['王力鸿'] = 66
print(stu_score)
#结果:{'王力鸿': 66, '周杰轮': 88, '林俊接': 77}
  1. 删除元素

    语法:字典.pop(Key),结果:获得指定Key的Value,同时字典被修改,指定Key的数据被删除

stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}

value =stu_score.pop("王力鸿")
print(stu_score)        #结果:{'周杰轮': 88, '林俊接': 77}
print(value)            #结果:99
  1. 清空字典

    语法:字典.clear(),结果:字典被修改,元素被清空

stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}

stu_score.clear()
print(stu_score)        #结果:{}
  1. 获取全部的key

    语法:字典.keys(),结果:得到字典中的全部Key

stu_score ={
    "王力鸿":99,
    "周杰轮":88,
    "林俊接":77}

key = stu_score.keys()
print(key)        #结果:dict_keys(['王力鸿', '周杰轮', '林俊接'])
  1. 遍历字典

    语法:for key in 字典.keys()

stu_score ={
   "王力鸿":99,
   "周杰轮":88,
   "林俊接":77}

keys = stu_score.keys()
for i in keys:
    print(f"学生:{i},分数:{stu_score[i]}")
#结果:学生:王力鸿,分数:99
      学生:周杰轮,分数:88
      学生:林俊接,分数:77

注意:字典不支持下标索引,所以同样不可以用while循环遍历

  1. 计算字典内的全部元素(键值对)数量

    语法:len(字典)

    结果:得到一个整数,表示字典内元素(键值对)的数量

stu_score ={
   "王力鸿":99,
   "周杰轮":88,
   "林俊接":77}
print(len(stu_score))   #结果:3

总结

编号操作说明
1字典[Key]获取指定Key对应的Value值
2字典[Key] = Value添加或更新键值对
3字典.pop(Key)取出Key对应的Value并在字典内删除此Key的键值对
4字典.clear()清空字典
5字典.keys()获取字典的全部Key,可用于for循环遍历字典
6len(字典)计算字典内的元素数量

经过上述对字典的学习,可以总结出字典有如下特点:

  • 可以容纳多个数据
  • 可以容纳不同类型的数据
  • 每一份数据是KeyValue键值对
  • 可以通过Key获取到Value,Key不可重复(重复会覆盖)
  • 不支持下标索引
  • 可以修改(增加或删除更新元素等)
  • 支持for循环,不支持while循环

练习题

有如下员工信息,请使用字典完成数据的记录。

并通过for循环,对所有级别为1级的员工,级别上升1级,薪水增加1000元

在这里插入图片描述

people ={
    "王力鸿":{"部门":"科技部","工资":3000,"级别":1},
    "周杰轮":{"部门":"市场部","工资":5000,"级别":2},
    "林俊接":{"部门":"市场部","工资":7000,"级别":3},
    "张学油":{"部门":"科技部","工资":4000,"级别":1},
    "刘德滑":{"部门":"市场部","工资":6000,"级别":2}}
print("全体成员信息如下:")
for i in people:
    print(i,people[i])
print("涨薪后信息为:")
for j in people:
    if people[j]["级别"]==1:
        people[j]["级别"] +=1
        people[j]["工资"]+=1000
    print(j, people[j])
#运行结果:
全体成员信息如下:
王力鸿 {'部门': '科技部', '工资': 3000, '级别': 1}
周杰轮 {'部门': '市场部', '工资': 5000, '级别': 2}
林俊接 {'部门': '市场部', '工资': 7000, '级别': 3}
张学油 {'部门': '科技部', '工资': 4000, '级别': 1}
刘德滑 {'部门': '市场部', '工资': 6000, '级别': 2}
涨薪后信息为:
王力鸿 {'部门': '科技部', '工资': 4000, '级别': 2}
周杰轮 {'部门': '市场部', '工资': 5000, '级别': 2}
林俊接 {'部门': '市场部', '工资': 7000, '级别': 3}
张学油 {'部门': '科技部', '工资': 5000, '级别': 2}
刘德滑 {'部门': '市场部', '工资': 6000, '级别': 2}

数据容器对比

列表元组字符串集合字典
元素数量支持多个支持多个支持多个支持多个支持多个
元素类型任意任意仅字符任意Key:ValueKey:除字典外任意类型Value:任意类型
下标索引支持支持支持不支持不支持
重复元素支持支持支持不支持不支持
可修改性支持不支持不支持支持支持
数据有序
使用场景可修改、可重复的一批数据记录场景不可修改、可重复的一批数据记录场景一串字符的记录场景不可重复的数据记录场景以Key检索Value的数据记录场景

基于各类数据容器的特点,它们的应用场景如下:

  • 列表:一批数据,可修改、可重复的存储场景
  • 元组:一批数据,不可修改、可重复的存储场景
  • 字符串:一串字符串的存储场景
  • 集合:一批数据,去重存储场景
  • 字典:一批数据,可用Key检索Value的存储场景

数据容器通用操作

1.数据容器尽管各自有各自的特点,但是它们也有通用的一些操作。

首先,在遍历上:

  • 5类数据容器都支持for循环遍历
  • 列表、元组、字符串支持while循环,集合、字典不支持(无法下标索引)

尽管遍历的形式各有不同,但是,它们都支持遍历操作。

2.除了遍历这个共性外,数据容器可以通用非常多的功能方法

len(容器):统计容器的元素个数

my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "hello"

print(len(my_list))	# 结果3
print(len(my_tuple))	# 结果5
print(len(my_str))	# 结果7

max(容器):统计容器的最大元素

my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "hello"

print(max(my_list))	# 结果3
print(max(my_tuple))	# 结果5
print(max(my_str))	# 结果o		根据ascall码表来比大小

min(容器):统计容器的最小元素

my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4, 5)
my_str = "hello"

print(min(my_list))	# 结果1
print(min(my_tuple))	# 结果1
print(min(my_str))	# 结果e

3.除了下标索引这个共性外,还可以通用类型转换

list(容器):将给定容器转换为列表

**str(容器):**将给定容器转换为字符串

**tuple(容器):**将给定容器转换为元组

set(容器):将给定容器转换为集合

4.通用排序功能

sorted(容器, [reverse=True])
将给定容器进行排序

注意,排序后都会得到列表(list)对象。

总览

功能描述
通用for循环遍历容器(字典是遍历key)
max容器内最大元素
min()容器内最小元素
len()容器元素个数
list()转换为列表
tuple()转换为元组
str()转换为字符串
set()转换为集合
sorted(序列, [reverse=True])排序,reverse=True表示降序得到一个排好序的列表

拓展:字符串比大小

在程序中,字符串所用的所有字符如:

  • 大小写英文单词
  • 数字
  • 特殊符号(!、\、|、@、#、空格等)都有其对应的ASCII码表值

每一个字符都能对应上一个:数字的码值字符串进行比较就是基于数字的码值大小进行比较的。

在这里插入图片描述

字符串是按位比较,也就是一位位进行对比,只要有一位大,那么整体就大。

在这里插入图片描述

在这里插入图片描述

第七章 文件操作

1.文件的编码

思考:计算机只能识别:0和1,那么我们丰富的文本文件是如何被计算机识别,并存储在硬盘中呢?

答案:使用编码技术(密码本)将内容翻译成0和1存入。

编码技术即:翻译的规则,记录了如何将内容翻译成二进制,以及如何将二进制翻译回可识别内容。

在这里插入图片描述

编码有许多,所以要使用正确的编码, 才能对文件进行正确的读写操作呢。

我们可以使用Windows系统自带的记事本,打开文件后,即可看出文件的编码是什么:
在这里插入图片描述

UTF-8是目前全球通用的编码格式除非有特殊需求,否则,一律以UTF-8格式进行文件编码即可。

2. 文件的读取

内存中存放的数据在计算机关机后就会消失。要长久保存数据,就要使用硬盘、光盘、U 盘等设备。为了便于数据的管理和检索,引入了“文件”的概念。

一篇文章、一段视频、一个可执行程序,都可以被保存为一个文件,并赋予一个文件名。操作系统以文件为单位管理磁盘中的数据。一般来说,文件可分为文本文件、视频文件、音频文件、图像文件、可执行文件等多种类别。
在这里插入图片描述

想想我们平常对文件的基本操作,大概可以分为三个步骤(简称文件操作三步走):① 打开文件 ② 读写文件 ③ 关闭文件
在这里插入图片描述

注意:可以只打开和关闭文件,不进行任何读写

open()打开函数

在Python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下

open(name, mode, encoding)

name:是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode:设置打开文件的模式(访问模式):只读、写入、追加等。
encoding:编码格式(推荐使用UTF-8
#示例代码
f = open("D:/a.txt", "r", encoding="UTF-8")
print(type(f))		#结果:<class '_io.TextIOWrapper'>

# encoding的顺序不是第三位,所以不能用位置参数,用关键字参数直接指定

注意:此时的fopen函数的文件对象,对象是Python中一种特殊的数据类型,拥有属性和方法,可以使用对象.属性或对象.方法对其进行访问,后续面向对象会进行详细的介绍。

模式描述
r以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。
w打开一个文件只用于写入。1.如果该文件已存在则打开文件,并从开头开始编辑,原有内容会被删除。2.如果该文件不存在,创建新文件。
a打开一个文件用于追加。1.如果该文件已存在,新的内容将会被写入到已有内容之后。2.如果该文件不存在,创建新文件进行写入。

read()方法:

文件对象.read(num)
#num表示要从文件中读取的数据的长度(单位是字节),如果没有传入num,那么就表示读取文件中所有的数据。

# 示例代码
f = open("D:/a.txt", "r", encoding="UTF-8")
a = f.read()
print(a)

readlines()方法:

#readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
f = open('D:/a.txt')
content = f.readlines()

# ['hello world\n', 'abcdefg\n', 'aaa\n', 'bbb\n', 'ccc']
print(content)

# 关闭文件
f.close()
#readline()方法:一次读取一行内容

f = open('D:/a.txt')

content = f.readline()
print(f'第一行:{content}')

content = f.readline()
print(f'第二行:{content}')

# 关闭文件
f.close()
#for循环读取文件行

for line in open("D:/a.txt", "r"):
    print(line)

# 每一个line临时变量,就记录了文件的一行数据

close() 关闭文件对象

f = open("D:/a.txt", "r")

f.close()

# 最后通过close,关闭文件对象,也就是关闭对文件的占用
# 如果不调用close,同时程序没有停止运行,那么这个文件将一直被Python程序占用。

with open 语法

with open("python.txt", "r") as f:
    f.readlines()

# 通过在with open的语句块中对文件进行操作
# 可以在操作完成后自动关闭close文件,避免遗忘掉close方法
操作功能
文件对象 = open(file, mode, encoding)打开文件获得文件对象
文件对象.read(num)读取指定长度字节不指定num读取文件全部
文件对象.readline()读取一行
文件对象.readlines()读取全部行,得到列表
for line in 文件对象for循环文件行,一次循环得到一行数据
文件对象.close()关闭文件对象
with open() as f通过with open语法打开文件,可以自动关闭

3.文件的写入

# 1. 打开文件
f = open('D:/a.txt', 'w')

# 2.文件写入
f.write('hello world')

# 3. 内容刷新
f.flush()	#可以直接f.close关闭,自动刷新

注意:

  • 直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区。
  • 当调用flush的时候,内容会真正写入文件。
  • 这样做是避免频繁的操作硬盘,导致效率下降(攒一堆,一次性写磁盘)。

写操作注意

  • 文件如果不存在,使用”w”模式,会创建新文件
  • 文件如果存在,使用”w”模式,会将原有内容清空

总结

  1. 写入文件使用open函数的”w”模式进行写入

  2. 写入的方法有:

    wirte(),写入内容

    flush(),刷新内容到硬盘中

  3. 注意事项:

    w模式,文件不存在,会创建新文件

    w模式,文件存在,会清空原有内容

    调用close(),自动使用flush()方法的功能

4.文件的追加

# 1. 打开文件,通过a模式打开即可
f = open('python.txt', 'a')

# 2.文件写入
f.write('hello world')

# 3. 内容刷新
f.flush()

注意:

  • a模式,文件不存在会创建文件
  • a模式,文件存在会在最后,追加写入文件

总结

  1. 追加写入文件使用open函数的”a”模式进行写入

  2. 追加写入的方法有(和w模式一致):

    wirte(),写入内容

    flush(),刷新内容到硬盘中

  3. 注意事项:

    a模式,文件不存在,会创建新文件

    a模式,文件存在,会在原有内容后面继续写入

    可以使用”\n”来写出换行符

5.文件备份案例

需求:有一份账单文件,记录了消费收入的具体记录,内容如下:

name,date,money,type,remarks

周杰轮,2022-01-01,100000,消费,正式
周杰轮,2022-01-02,300000,收入,正式
周杰轮,2022-01-03,100000,消费,测试
林俊节,2022-01-01,300000,收入,正式
林俊节,2022-01-02,100000,消费,测试
林俊节,2022-01-03,100000,消费,正式
林俊节,2022-01-04,100000,消费,测试
林俊节,2022-01-05,500000,收入,正式
张学油,2022-01-01,100000,消费,正式
张学油,2022-01-02,500000,收入,正式
张学油,2022-01-03,900000,收入,测试
王力鸿,2022-01-01,500000,消费,正式
王力鸿,2022-01-02,300000,消费,测试
王力鸿,2022-01-03,950000,收入,正式
刘德滑,2022-01-01,300000,消费,测试
刘德滑,2022-01-02,100000,消费,正式
刘德滑,2022-01-03,300000,消费,正式

将内容复制并保存为 bill.txt文件

我们现在要做的就是:

  • 读取文件
  • 将文件写出到bill.txt.bak文件作为备份
  • 同时,将文件内标记为测试的数据行丢弃

实现思路:

  1. open和r模式打开一个文件对象,并读取文件
  2. open和w模式打开另一个文件对象,用于文件写出
  3. for循环内容,判断是否是测试不是测试就write写出,是测试就continue跳过
  4. 将2个文件对象均close()
# 1. 打开文件
fr = open('D:/bill.txt', 'r', encoding='UTF-8')
fw = open('D:/bill.txt.bak', 'w', encoding='UTF-8')
#2.写入文件
for line in fr:
    line = line.strip()         #去掉前后空格
    if line.split(",")[4] == "测试":#
        continue
    fw.write(line)
    fw.write("\n")  #因为前面对内容进行了strip()操作,所以要手动的写出换行符
# 3. 关闭,内容刷新
fw.close()
fr.close()

第八章 Pyhton异常、模块、包

1.异常

当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的==“异常”,== 也就是我们常说的BUG

异常演示:

例如:以r方式打开一个不存在的文件。

f = open('linux.txt', 'r')

在这里插入图片描述

2.异常捕获

世界上没有完美的程序,任何程序在运行的过程中,都有可能出现:异常,也就是出现bug,导致程序无法完美运行下去。

我们要做的,不是力求程序完美运行。而是在力所能及的范围内,对可能出现的bug,进行提前准备、提前处理。

这种行为我们称之为:异常处理(捕获异常)

为什么需要捕获异常?

当我们的程序遇到了BUG, 那么接下来有两种情况:

① 整个程序因为一个BUG停止运行

② 对BUG进行提醒, 整个程序继续运行

显然在之前的学习中, 我们所有的程序遇到BUG就会出现①的这种情况, 也就是整个程序直接奔溃.但是在真实工作中, 我们肯定不能因为一个小的BUG就让整个程序全部奔溃, 也就是我们希望的是达到② 的这种情况那这里我们就需要使用到捕获异常捕获异常的作用在于:提前假设某处会出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段。

1.捕获常规异常—基本语法

这个基本异常捕获已经可以捕获全部异常,第四点没必要用

try:
    可能发生错误的代码
except:
    如果出现异常执行的代码
# 1.基本捕获语法
try:
    f = open("D:/abc.txt", "r", encoding="UTF-8")
except:
    print("出现异常了,因为文件不存在,我将open的模式,改为w模式去打开")
    f = open("D:/abc.txt", "w", encoding="UTF-8")

2.捕获指定异常

# 2.捕获指定的异常
try:
    print(name)
    # 1 / 0
except NameError as e:
    print("出现了变量未定义的异常")
    print(e)

在这里插入图片描述

① 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。 ② 一般try下方只放一行尝试执行的代码。

把捕获异常的原因存到e变量里面,打印出来

3.捕获多个异常

当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。

# 3.捕获多个异常
try:
    # 1 / 0
    print(name)
except (NameError, ZeroDivisionError) as e:
    print("出现了变量未定义 或者 除以0的异常错误")
# 未正确设置捕获异常类型,将无法捕获异常

在这里插入图片描述

4.捕获所有异常

else表示的是如果没有异常要执行的代码。

try:
    f = open("D:/123.txt", "r", encoding="UTF-8")
except Exception as e:
    print("出现异常了")
    f = open("D:/123.txt", "w", encoding="UTF-8")
else:
    print("好高兴,没有异常。")

在这里插入图片描述

5.异常的finally

finally表示的是无论是否异常都要执行的代码,例如关闭文件。

try:
    f = open("D:/123.txt", "r", encoding="UTF-8")
except Exception as e:
    print("出现异常了")
    f = open("D:/123.txt", "w", encoding="UTF-8")
else:
    print("好高兴,没有异常。")
finally:
    print("我是finally,有没有异常我都要执行")
    f.close()

在这里插入图片描述

3.异常的传递

异常是具有传递性的。

当函数func01中发生异常, 并且没有捕获处理这个异常的时候, 异常会传递到函数func02, 当func02也没有捕获处理这个异常的时候main函数会捕获这个异常, 这就是异常的传递性。

在这里插入图片描述

提示: 当所有函数都没有捕获异常的时候, 程序就会报错

利用异常具有传递性的特点, 当我们想要保证程序不会因为异常崩溃的时候, 就可以在main函数中设置异常捕获, 由于无论在整个程序哪里发生异常, 最终都会传递到main函数中, 这样就可以确保所有的异常都会被捕获

4.python模块

Python 模块(Module),是一个 Python 文件,以 .py 结尾. 模块能定义函数,类和变量,模块里也能包含可执行的代码。

模块的作用: python中有很多各种不同的模块, 每一个模块都可以帮助我们快速的实现一些功能, 比如实现和时间相关的功能就可以使用time模块我们可以认为一个模块就是一个工具包, 每一个工具包中都有各种不同的工具供我们使用,进而实现各种不同的功能。

**大白话:**模块就是一个Python文件,里面有类、函数、变量等,我们可以拿过来用(导入模块去使用)

1.模块导入方式

模块在使用前需要先导入 导入的语法如下:

[form 模块名] import [模块||变量|函数|*][as 别名]

常用的组合形式如:

  1. import 模块名
  2. from 模块名 import 类、变量、方法等
  3. from 模块名 import *
  4. import 模块名 as 别名
  5. from 模块名 import 功能名 as 别名

基本语法:

1.import模块名

import会把里面所有的模块都会导入进来

import 模块名
import 模块名1,模块名2

模块名.功能名()
# 导入时间模块
import time
print("开始") 
time.sleep(1)# 让程序睡眠1秒(阻塞)
print("结束")

2.from 模块名 import 功能名

因为导入的模块里面的函数不一定都会用上,所以只需要导入用到的即可

from 模块名 import 功能名

功能名()
# 导入时间模块中的sleep方法
from time import sleep
print("开始")# 让程序睡眠1秒(阻塞)
sleep(1)
print("结束")

**3.from 模块名 import ***

导入模块的全部功能,与第一个一样,区别在于,不用加 . 了。

from 模块名 import *

功能名()
# 导入时间模块中所有的方法
from time import *
print("开始")# 让程序睡眠1秒(阻塞)
sleep(1)
print("结束")

2.as定义别名

可以把一些长模块名重命名为短的,,方便

基本语法:

# 模块定义别名
import 模块名 as 别名

# 功能定义别名
from 模块名 import 功能 as 别名

案例:

# 模块别名
import time as tt
tt.sleep(2)
print('hello')

# 功能别名
from time import sleep as sl
sl(2)
print('hello')

5.自定义模块

Python中已经帮我们实现了很多的模块. 不过有时候我们需要一些个性化的模块, 这里就可以通过自定义模块实现, 也就是自己制作一个模块。

**案例:**新建一个Python文件,命名为my_module1.py,并定义test函数

在这里插入图片描述在这里插入图片描述

注意: 每个Python文件都可以作为一个模块,模块的名字就是文件的名字. 也就是说自定义模块名必须要符合标识符命名规则

# 导入不同模块的同名功能
from my_module1 import test
from my_module2 import test
test(1, 2)

注意事项:当导入多个模块的时候,且模块内有同名功能. 当调用这个同名功能的时候,调用到的是后面导入的模块的功能。

6.测试模块

在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,这个开发人员会自行在py文件中添加一些测试信息,例如,在my_module1.py文件中添加测试代码test(1,1)

#my_module1.py
#当其他文件调用这个模块时,会从上到下运行一遍,这个时候test函数就会被运行,但是这个文件我又不想删除,以后想要做测试用,那么我应该怎么做呢
def test(a, b):
    print(a + b)

test(1, 1)
#my_module1.py
def test(a, b):
    print(a + b)

# 只在当前文件中调用该函数,其他导入的文件内不符合该条件,则不执行test函数调用
if __name__ == '__main__':
    test (1, 1)

在每个文件中都有一个内部变量name,当我在运行这个文件时,他就是main函数,但是如果是被其他文件调用过来的,则不是。

7.__ all __

如果一个模块文件中有__all__变量,当使用from xxx import *导入时,只能导入这个列表中的元素

__all__变量可以控制import *的时候哪些功能可以被导入

在这里插入图片描述

8.自定义包

基于Python模块,我们可以在编写代码的时候,导入许多外部代码来丰富功能。

但是,如果Python的模块太多了,就可能造成一定的混乱,这个时候就可以通过Python包的功能来管理。

当我创建软件包时,会自动生成init.py文件

包的作用: 当我们的模块文件越来越多时,包可以帮助我们管理这些模块, 包的作用就是包含多个模块,但包的本质依然是模块

什么是包?

从物理上看,包就是一个文件夹,在该文件夹下包含了一个 init.py 文件,该文件夹可用于包含多个模块文件

从逻辑上看,包的本质依然是模块

在这里插入图片描述

操作流程

1.新建软件包

在这里插入图片描述

2.软件包与文件夹的区别,会在下面自动生成init.py(一般为空)。
在这里插入图片描述

"""
演示自定义模块1
my_module1.py
"""

def info_print1():
    print("我是模块1的功能函数代码")
"""
自定义模块2
my_module2.py
"""

def info_print2():
    print("我是模块2的功能函数代码")
# 创建一个包
# 导入自定义的包中的模块,并使用
#第一种导入方法
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
#可以合起来写from my_package import my_module1,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__ = [],控制允许导入的模块列表

在这里插入图片描述

9.安装第三方包

我们知道,包可以包含一堆的Python模块,而每个模块又内含许多的功能。

所以,我们可以认为:一个包,就是一堆同类型功能的集合体。

在Python程序的生态中,有许多非常多的第三方包(非Python官方),可以极大的帮助我们提高开发效率,

如:

  1. 科学计算中常用的:numpy包
  2. 数据分析中常用的:pandas包
  3. 大数据计算中常用的:pyspark、apache-flink包
  4. 图形可视化常用的:matplotlib、pyecharts
  5. 人工智能常用的:tensorflow等

这些第三方的包,极大的丰富了Python的生态,提高了开发效率。但是由于是第三方,所以Python没有内置,所以我们需要安装它们才可以导入使用哦。

第三方包的安装非常简单,我们只需要使用Python内置的pip程序即可。

安装:在命令提示符程序,输入:pip install 包名称即可通过网络快速安装第三方包。

在这里插入图片描述

pip的网络优化:

由于pip是连接的国外的网站进行包的下载,所以有的时候会速度很慢。

我们可以通过如下命令,让其连接国内的网站进行包的安装:

 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名称

https://pypi.tuna.tsinghua.edu.cn/simple 是清华大学提供的一个网站,可供pip程序下载第三方包

  • PyCharm安装第三方包

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/703689.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

从sub-VP SDE形式推导出扰动核(高斯分布)的均值和方差【论文精读】

从sub-VP SDE形式推导出扰动核&#xff08;高斯分布&#xff09;的均值和方差【论文精读】 讲解视频 B站视频&#xff1a;sub-VP SDE形式推导出扰动核&#xff08;高斯分布&#xff09;的均值和方差 讲解目录 &#xff08;0&#xff09;sub-VP SDE形式由来&#xff1a;有良…

14、modbus poll 使用教程小记1

开发平台&#xff1a;Win10 64位 Modbus Slave版本&#xff1a;64位 7.0.0 Modbus Poll版本&#xff1a;64位 7.2.2 因为项目中经常会用到modbus协议&#xff0c;所以就避免不了的要使用modbus测试工具&#xff0c;Modbus Slave/Poll无疑是众多测试工具中应用最广泛的。 文章目…

0602 差分式放大电路

差分式放大电路 差分放大电路的基本概念直接耦合放大电路中的零点漂移 6.2.1 差分式放大的基本概念 6.2.2 直接耦合放大电路中的零点漂移 6.2.3 BJT射极耦合差分式放大电路 差分放大电路的基本概念 直接耦合放大电路中的零点漂移

WebSocket 快速入门 与 应用

WebSocket 是一种在 Web 应用程序中实现实时、双向通信的技术。它允许客户端和服务器之间建立持久性的连接&#xff0c;以便可以在两者之间双向传输数据。 以下是 WebSocket 的一些关键特点和工作原理&#xff1a; 0.特点&#xff1a; 双向通信&#xff1a;WebSocket 允许服务…

MySQL密码自动过期配置

目录 一、密码自动过期 1、临时 2、永久 3、查看 4、账号设置 一、密码自动过期 登录数据库查看是否生效 mysql -u root -p #查看数据库账号状态 select user,host,password_expired,password_lifetime,password_last_changed,account_locked from mysql.user; 1、passwo…

【博士每天一篇文献-算法】Progressive Neural Networks

阅读时间&#xff1a;2023-12-12 1 介绍 年份&#xff1a;2016 作者&#xff1a;Andrei A. Rusu,Neil Rabinowitz,Guillaume Desjardins,DeepMind 研究科学家,也都是EWC(Overcoming catastrophic forgetting in neural networks)算法的共同作者。 期刊&#xff1a; 未录用&am…

2024-2025最新软考系统架构设计师的复习资料教材,解决如何快速高效通过该考试,试题的重点和难点在哪里?案例分析题和论文题的要点和踩坑点分析

目录 引言考试概述 考试结构考试内容 复习策略 制定复习计划学习资源 知识点详解 系统架构基础设计原则与模式系统分析与设计软件开发过程项目管理系统集成性能与优化安全性设计新兴技术 试题解析 选择题案例分析题论文题 重点与难点分析模拟试题与答案参考资料总结 引言 系…

transformers 阅读:BERT 模型

前言 想深入理解 BERT 模型&#xff0c;在阅读 transformers 库同时记录一下。 笔者小白&#xff0c;错误的地方请不吝指出。 Embedding 为了使 BERT 能处理大量下游任务&#xff0c;它的输入可以明确表示单一句子或句子对&#xff0c;例如<问题&#xff0c;答案>。 …

RK3568笔记三十一:ekho 6.3 文本转语音移植

若该文为原创文章&#xff0c;转载请注明原文出处。 移植的目的是在在OCR识别基础上增加语音播放&#xff0c;把识别到的文字直接转TTS播报出来&#xff0c;形成类似点读机的功能。 1、下载文件 libsndfile-1.0.28.tar.gz ekho-6.3.tar.xz 2、解压 tar zxvf libsndfile-1.0…

使用MATLAB对地铁站、公交站等求解最短路径

使用MATLAB对城市的地铁站、公交站等站点&#xff0c;根据站点的经纬度坐标和彼此之间的权重&#xff0c;求解其最短路径、途径站点和路程 已知的数据如图&#xff0c;是西安市地铁站点的数据&#xff0c;保存在一个Excel里 如图&#xff0c;每列的内容都在上面&#xff0c;不…

smart_rtmpd 的后台管理

高效的流媒体服务器 smart_rtmpd&#xff0c;您值得拥有 smart_rtmpd 的下载地址 https://github.com/superconvert/smart_rtmpd smart_rtmpd 的管理后台 https://github.com/superconvert/smart_rtmpd/edit/master/web%20manager/src/README.md web 管理后台说明 web 管理…

鹏城实验室PCLmed团队荣获ImageCLEFmedical 2024冠军,实现医疗图像解读新突破

在近期举行的ImageCLEFmedical 2024全球医疗图像分析和文本生成竞赛中&#xff0c;鹏城实验室专注于医学模型研究的PCLmed团队凭借卓越的技术实力和创新的解决方案&#xff0c;从来自世界各地的61支参赛队伍中脱颖而出&#xff0c;斩获冠军殊荣。这一成就不仅彰显了团队在医疗图…

树结构的实现

树的概念 树是一种非线性的数据结构&#xff0c;它是由n个有限节点组成一个具有层次关系的集合&#xff0c;它看起来像棵树&#xff0c;所以称其为“树”。如下图&#xff1a; 树可以分为根和子树&#xff0c;而子树又可以被分为根和子树&#xff0c;故我们可以用递归对其进行实…

基恩士LT-X8000A的IP地址

在这里插入图片描述 192.168.0.256 192.168.0.1 LT-X8000A

Kotlin 协程真的轻量吗?

前言 在官方文档的介绍中,提到了: 协程是轻量的 并给出了一个例子: fun main() = runBlocking {repeat(50_000) {// 启动大量的协程launch {delay

Button按钮类

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 按钮是GUI界面中应用最为广泛的控件&#xff0c;它常用于捕获用户生成的单击事件&#xff0c;其最明显的用途是触发绑定到一个处理函数。 wxPython类…

180.二叉树:二叉搜索树(力扣)

代码解决 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* Tre…

MFC上下文菜单与定时器学习笔记

本博文简单介绍了上下文菜单以及定时器的知识内容&#xff0c;作为笔记发表在csdn上面。 在这里插入图片描述 菜单资源的使用 添加菜单资源加载菜单资源&#xff1a; 注册窗口类时设置菜单创建窗口传参设置菜单在主窗口WM_CREATE消息中利用SetMenu函数设置 加载菜单资…

Python学习笔记6:pychram相关知识及安装教程,后续需要学习的入门知识

上篇文章说了&#xff0c;今天去公司重新装一下IDE&#xff0c;最后也是把过程这边再记录一下&#xff0c;有需要的可以参考一下。 关于pychram pychram是什么&#xff1f; PyCharm是由JetBrains公司开发的一款流行的Python集成开发环境&#xff08;IDE&#xff09;。它专为…

RAM IP核配置

REVIEW 之前已经学习过&#xff1a; ROM:FPGA寄存器 Vivado IP核-CSDN博客 串口接收&#xff1a;Vivado 串口接收优化-CSDN博客 1. 今日摸鱼计划 RAM创建与测试 小梅哥视频&#xff1a; 21C_嵌入式块存储器RAM介绍_哔哩哔哩_bilibili 21D_嵌入式块存储器RAM实现和仿真_哔哩…