字面量
常用的值类型
Python中常用的有6种值 (数据)的类型
注释
注释的分类
- 单行注释: 以 #开头,#右边 的所有文字当作说明,而不是真正要执行的程序,起辅助说明作用
注意,#号和注释内容一般建议以一个空格隔开
多行注释: 以 一对三个双引号 引起来 ("""注释内容""")来解释说明一段代码的作用使用方法
变量
通过 key=value定义变量
数据类型
type()语句
type(被查看类型的数据)
变量有类型吗?
我们通过type(变量)可以输出类型,这是查看变量的类型还是数据的类型?
查看的是:变量存储的数据的类型。因为,变量无类型,但是它存储的数据有。
类型转换
为什么要转换类型
- 数据类型转换,将会是我们以后经常使用的功能。如:
- 从文件中读取的数字,默认是字符串,我们需要转换成数字类型
- 后续学习的input()语句,默认结果是字符串,若需要数字也需要转换
- 将数字转换成字符串用以写出到外部系统
- 等等
常见转换语句
标识符
标识符命名规则
Python中,标识符命名的规则主要有3类:
- 内容限定
- 大小写敏感
- 不可使用关键字
标识符命名规则- 内容限定
标识符命名中,只允许出现:
- 英文
- 中文
- 数字
- 下划线 ( _ )
这四类元素。
其余任何内容都不被允许
运算符
算数运算符
赋值运算符
复合赋值运算符
比较运算符
字符串
字符串(string),又称文本,是由任意数量的字符如中文、英文、各类符号、数字等组成。所以叫做字符的串
如:
- "黑马程序员"
- "学Python来黑马"
- "!@#$%^&"
- "传智教育的股票代码是:003032"
Python中,字符串需要用双引号(")包围起来
被引号包围起来的,都是字符串
字符串定义的方法
字符串的三种定义方式
三引号定义法,和多行注释的写法一样,同样支持换行操作。
使用变量接收它,它就是字符串
不使用变量接收它,就可以作为多行注释使用
字符串的引号嵌套
思考: 如果我想要定义的字符串本身,是包含:单引号、双引号自身呢?如何写?
- 单引号定义法,可以内含双引号
- 双引号定义法,可以内含单引号
- 可以使用转义字符 (\)来将引号解除效用,变成普通字符串
字符串拼接
如果我们有两个字符串(文本)字面量,可以将其拼接成一个字符串,通过+号即可完成,如:
“引引加加”
不过一般,单纯的2个字符串字面量进行拼接显得很呆,一般,字面量和变量或变量和变量之间会使用拼接,如:
字符串格式化
我们可以通过如下语法,完成字符串和变量的快速拼接。
其中的 %s
- % 表示: 我要占位
- s 表示: 将变量变成字符串放入占位的地方
所以,综合起来的意思就是:我先占个位置,等一会有个变量过来,我把它变成字符串放到占位的位置
字符串格式化- 数字精度控制
如下代码,完成字符串、整数、浮点数,三种不同类型变量的占位
细心的同学可能会发现:
浮点数19.99,变成了19.990000输出
我们可以使用辅助符号"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
字符串格式化- 快速写法
目前通过%符号占位已经很方便了,还能进行精度控制。
可是追求效率和优雅的Python,是否有更加优雅的方式解决问题呢?
那当然:有
通过语法:f"内容{变量}"的格式来快速格式化
看如下代码
注意此处加了在print括号内加了f才能实现花括号内加变量的功能
字符串格式化- 表达式的格式化
那么,对于字符串格式化,能否直接格式化一个表达式呢?
可以,上代码:
在无需使用变量进行数据存储的时候,可以直接格式化表达式,简化代码哦
该种方法将在句尾用%( )来给占位符输入内容
总结:
- 表达式是什么?
表达式就是一个具有明确结果的代码语句,如1+1、type(“字符串”)、3*5等
在变量定义的时候,如age=11+11,等号右侧的就是表达式,也就是有具体的结果,将结果赋值给了等号左侧的变量
- 如何格式化表达式?
- f"{表达式}"
- "%s\%d\%f%(表达式、表达式、表达式)
input语句(函数)
我们前面学习过print语句 (函数),可以完成将内容 (字面量、变量等)输出到屏幕上。
在Python中,与之对应的还有一个input语句,用来获取键盘输入。
- 数据输出:print
- 数据输入:input
使用上也非常简单:
- 使用input()语句可以从键盘获取输入
- 使用一个变量接收(存储)input语句获取的键盘输入数据即可
print("请告诉我你是谁?")
name=input()
print("Get!!!你是:%s"%name)
input( )语句其实是可以在要求使用者输入内容前,输出提示内容的哦,方式如下:
name=input("请告诉我你是谁?")
print("Get!!!你是:%s"%name)
如图,在input的括号内直接填入提示内容即可。
要注意,无论键盘输入什么类型的数据,获取到的数据永远都是字符串类型
if判断语句
# 定义变量
age=30
#进行判断
if age >=18:
print("我已经成年了")
在if内的语句要缩进,if外的语句不用缩进
总结:
if else 语句
if elif语句
判断语句的嵌套
基础语法格式如下
如上图,第二个if,属于第一个if内,只有第一个if满足条件,才会执行第二个if
嵌套的关键点,在于: 空格缩进
通过空格缩进,来决定语句之间的:层次关系
while循环语句
i=0
while i<100
print("小美,我喜欢你")
i+=1
for循环语句
与js的for in一样,依次遍历。可实现c里的for的功能,甚至更加好用
for循环的变量作用域
- for循环中的临时变量,其作用域限定为:
- 循环内
- 这种限定:
- 是编程规范的限定,而非强制限定
- 不遵守也能正常运行,但是不建议这样做
- 如需访问临时变量,可以预先在循环外定义它
range语句
for循环语句,本质上是遍历:序列类型。
尽管除字符串外,其它的序列类型目前没学习到,但是不妨碍我们通过学习range语句,获得一个简单的数字序列。
语法1:
range()
获取一个从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]
continue
continue关键字用于:中断本次循环,直接进入下一次循环
continue可用于: for循环和while循环,效果一致
左侧代码:
- 在循环内,遇到continue就结束当次循环,进行下一次
- 所以,语句2是不会执行的。
应用场景:
在循环中,因某些原因,临时结束本次循环
break
break关键字用于:直接结束循环
break可以用于:for循环和while循环,效果一致
左侧代码:
- 在循环内,遇到break就结束循环了
- 所以,执行了语句1后,直接执行语句3了
函数
函数的定义
函数的调用
注意事项
- 参数如不需要,可以省略(后续章节讲解)
- 返回值如不需要,可以省略 (后续章节讲解 )
- 函数必须先定义后使用
函数的传入参数
- 函数定义中,提供的x和y,称之为: 形式参数(形参),表示函数声明将要使用2个参数
- 参数之间使用逗号进行分隔。
- 函数调用中,提供的5和6,称之为:实际参数(实参),表示函数执行时真正使用的参数值
- 传入的时候,按照顺序传入数据,使用逗号分隔
返回值
如图代码
定义两数相加的函数功能。完成功能后,会将相加的结果返回给函数调用者
所以,变量r接收到了函数的执行结果。
综上所述:
所谓“返回值”就是程序中函数完成事情后,最后给调用者的结果
none类型
None作为一个特殊的字面量,用于表示:空、无意义,其有非常多的应用场景。
- 用在函数无返回值上
- 用在if判断上
- 在if判断中,None等同于False
- 一般用于在函数中主动返回None,配合if判断做相关处理
- 用于声明无内容的变量上
- 定义变量,但暂时不需要变量有具体值,可以用None来代替
函数的说明文档
函数是纯代码语言,想要理解其含义,就需要一行行的去阅读理解代码,效率比较低
我们可以给函数添加说明文档,辅助理解函数的作用
语法如下:
通过多行注释的形式,对函数进行说明解释
- 内容应写在函数体之前
什么是函数的嵌套
所谓函数嵌套调用指的是一个函数里面又调用了另外一个函数
局部变量
变量作用域指的是变量的作用范围(变量在哪里可用,在哪里不可用)
主要分为两类: 局部变量和全局变量
所谓局部变量是定义在函数体内部的变量,即只在函数体内部生效
变量a是定义在 'testA' 函数内部的变量,在函数外部访问则立即报错
局部变量的作用: 在函数体内部,临时保存数据,即当函数调用完成后,则销毁局部变量
全局变量
所谓全局变量,指的是在函数体内、外都能生效的变量
思考: 如果有一个数据,在函数A和函数B中都要使用,该怎么办?
答:将这个数据存储在一个全局变量里面
# 定义全局变量a
num = 100
def testA():
print(num) # 访问全局变量num,并打印变量num存储的数据
def testB():
print(num) # 访问全局变量num,并打印变量num存储的数据
testA() # 100
testB() # 100
global关键字
使用 global关键字 可以在函数内部声明变量为全局变量,如下所示
num = 100
def testA():
print(num)
def testB():
# globa1 关键字声明a是全局变量
globa num
num = 200
print(num)
testA() #结果100
testB() #结果200
print(f'全局变量num = {num}') # 结果: 全局变量num = 200
python容器
列表
列表的定义
基本语法:
# 字面量
[元素1,元素2,元素3,元素4,...]
# 定义变量
变量名称 = [元素1,元素2,元素3,元素4,...]
# 定义空列表
变量名称 = []
变量名称 = list()
列表内的每一个数据,称之为元素
- 以[ ]作为标识
- 列表内每一个元素之间用,逗号隔开
嵌套列表的定义
my_list =[[1,2,3],[4,5,6]]
注意: 列表可以一次存储多个数据,且可以为不同的数据类型,支持嵌套
列表的下标
如何从列表中取出特定位置的数据呢?
我们可以使用:下标索引
如图,列表中的每一个元素,都有其位置下标索引,从前向后的方向,从0开始,依次递增
我们只需要按照下标索引,即可取得对应位置的元素。
# 语法:列表[下标索引]
name_list = ['Tom','Lily','Rose']
print(name_list[0]) # 结果: Tom
print(name_list[1]) # 结果: Lily
print(name_list[2]) # 结果: Rose
列表的下标(索引) - 反向
或者,可以反向索引,也就是从后向前: 从-1开始,依次递减 (-1、-2、-3......)
如图,从后向前,下标索引为:-1、-2、-3,依次递减。
如果列表是嵌套的列表,同样支持下标索引
与二维数组一样
回忆:函数是一个封装的代码单元,可以提供特定功能。
在Python中,如果将函数定义为class (类)的成员,那么函数会称之为: 方法
方法和函数功能一样,有传入参数,有返回值,只是方法的使用格式不同:
函数的使用: num=add(1,2)
方法的使用:student =Student( )
num = student.add(1,2)
在调用类和函数时是类似的,都要用括号。
其中,调用类分为两步
- 创建类对象
- 调用实例化的对象
class Student:
def add(self,x,y):
return x + y
student=Student() #创建类对象
num=student.add(1,2)调用实例化对象
列表的查询功能(方法)
- 查找某元素的下标
功能: 查找指定元素在列表的下标,如果找不到,报错ValueError
语法: 列表.index(元素)
index就是列表对象 (变量) 内置的方法 (函数)
列表的修改功能(方法)
- 修改特定位置(索引)的元素值:
语法: 列表[下标]= 值
可以使用如上语法,直接对指定下标(正向、反向下标均可)的值进行:重新赋值(修改)
- 插入元素:
语法: 列表.insert(下标,元素),在指定的下标位置,插入指定的元素
- 追加元素
语法: 列表.append(元素),在指定的下标位置,插入指定的元素
插入元素时传入的数字是待插入元素准备插入到的序号,原元素和后面的元素被挤到后面去
- 追加元素方式2
语法: 列表.extend(其它数据容器),将其它数据容器的内容取出,依次追加到列表尾部
- 删除元素
语法1:del列表[下标]
语法2:列表.pop(下标)
my_list = [1,2,3]
#方式1
del my_list[0]
print(my_list) # 结果: [2,3]
#方式2
my_list.pop(0)
print(my_list) # 结果: [2,3]
- 删除某元素在列表中的第一个匹配项
语法: 列表.remove(元素)
- 清空列表内容,语法: 列表.clear()
- 统计某元素在列表内的数量
语法: 列表.count(元素)
列表的查询功能(方法)
- 统计列表内,有多少元素
语法: len(列表)
可以得到一个int数字,表示列表内的元素数量
列表的遍历- while循环
既然数据容器可以存储多个元素,那么,就会有需求从容器内依次取出元素进行操作。
将容器内的元素依次取出进行处理的行为,称之为:遍历、迭代。
如何遍历列表的元素呢?
- 可以使用前面学过的while循环
如何在循环中取出列表的元素呢?
- 使用列表[下标]的方式取出
循环条件如何控制?
- 定义一个变量表示下标,从0开始
- 循环条件为下标值<列表的元素数量
列表的遍历- for循环
除了while循环外,Python中还有另外一种循环形式: for循环。
对比while,for循环更加适合对列表等数据容器进行遍历
语法:
表示,从容器内,依次取出元素并赋值到临时变量上。
在每一次的循环中,我们可以对临时变量(元素)进行处理。
def list_for_func()
#使用for循环遍历列表的演示函数
my_list = [1,2,3,4,5]
# for 临时变量 in 数据容器:
for element in my_list:
print(f"列表的元素有: {element}")
return:none
while循环和for循环的对比
while循环和for循环,都是循环语句,但细节不同:
- 在循环控制上:
-
- while循环可以自定循环条件,并自行控制
- for循环不可以自定循环条件,只可以一个个从容器内取出数据
- 在无限循环上:
-
- while循环可以通过条件控制做到无限循环
- for循环理论上不可以,因为被遍历的容器容量不是无限的
- 在使用场景上:
-
- while循环适用于任何想要循环的场景
- for循环适用于,遍历数据容器的场景或简单的固定次数循环场景
元组
元组定义:定义元组使用小括号,且使用逗号隔开各个数据,数据可以是不同的数据类型。
# 定义元组字面量
(元素,元素,......,元素)
# 定义元组变量
变量名称 = (元素,元素,......,元素)
# 定义空元组
变量名称 = () #方式1
变量名称 = tuple() #方式2
元组的相关操作- 注意事项
不可以修改元组的内容,否则会直接报错
可以修改元组内的list的内容 (修改元素、增加、删除、反转等)
元组的特点
经过上述对元组的学习,可以总结出列表有如下特点:
- 可以容纳多个数据
- 可以容纳不同类型的数据 (混装)
- 数据是有序存储的 (下标索引)
- 允许重复数据存在
- 不可以修改 (增加或删除元素等)
- 支持for循环
多数特性和list一致,不同点在于不可修改的特性
字符串
字符串的下标(索引)
和其它容器如:列表、元组一样,字符串也可以通过下标进行访问
- 从前向后,下标从0开始.
- 从后向前,下标从-1开始
同元组一样,字符串是一个: 无法修改的数据容器
所以:
- 修改指定下标的字符 (如:字符串[0]=“a”)
- 移除特定下标的字符 (如: del 字符串[0]、字符串.remove()、字符串.pop()等)
- 追加字符等 (如:字符串.append())
均无法完成。如果必须要做,只能得到一个新的字符串,无法修改
查找特定字符串的下标索引值
语法: 字符串.index(字符串)
打印起始的序号
字符串的替换
语法: 字符串.replace(字符串1,字符串2)
功能: 将字符串内的全部: 字符串1,替换为字符串2
注意: 不是修改字符串本身,而是得到了一个新字符串哦
字符串的分割
语法: 字符串.split(分隔符字符串 )
功能: 按照指定的分隔符字符串,将字符串划分为多个字符串,并存入列表对象中
注意: 字符串本身不变,而是得到了一个列表对象
# split方法
my_str = "hello python itheima itcast!
my_str_list = my_str.split(" ")
print(f"将字符串(my_str}进行split切分后得到: {my_str_list},类型是: {type(my_str_list)}")
结果:
字符串的规整操作(去前后空格和结尾的换行符)
语法: 字符串.strip()
字符串的规整操作(去前后指定字符串)
语法: 字符串.strip(字符串)
注意,传入的是“12” 其实就是:”1”和”2”都会移除,是按照单个字符。
编号 | 操作 | 说明 |
1 | 字符串[下标] | 根据下标索引取出特定位置字符 |
2 | 字符串.index(字符串) | 查找给定字符的第一个匹配项的下标 |
3 | 字符串.repce(字符串1,字符串2) | 将字符串内的全部字符串1,替换为字符串2 不会修改原字符串,而是得到一个新的 |
4 | 字符串.split(字符串) | 按照给定字符串,对字符串进行分隔 不会修改原字符串,而是得到一个新的列表 |
5 | 字符串.strip() 字符串.strip(字符串) | 移除首尾的空格和换行符或指定字符串 |
6 | 字符串.count(字符串) | 统计字符串内某字符串的出现次数 |
7 | len(字符串) | 统计字符串的字符个数 |
字符串的遍历
同列表、元组一样,字符串也支持while循环和for循环进行遍历
总结
作为数据容器,字符串有如下特点:
- 只可以存储字符串
- 长度任意 (取决于内存大小)
- 支持下标索引
- 允许重复字符串存在
- 不可以修改 (增加或删除元素等)
- 支持for循环
序列
序列是指:内容连续、有序,可使用下标索引的一类数据容器
列表、元组、字符串,均可以可以视为序列。
序列的常用操作 - 切片
序列支持切片,即: 列表、元组、字符串,均支持进行切片操作
切片: 从一个序列中,取出一个子序列
语法: 序列[起始下标:结束下标:步长]
表示从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列:
- 起始下标表示从何处开始,可以留空,留空视作从头开始
- 结束下标(不含)表示何处结束,可以留空,留空视作截取到结尾
- 步长表示,依次取元素的间隔
-
- 步长1表示,一个个取元素
- 步长2表示,每次跳过1个元素取
- 步长N表示,每次跳过N-1个元素取
- 步长为负数表示,反向取(注意,起始下标和结束下标也要反向标记)
对于一个切片操作,传入的起始位置会留在串中,但是结束位置不会留在串中
name='万过薪月,员序程马黑,nohtyP学'
result=name[9:4:-1] # 9对应黑 4对应',' 因此'黑'被切下留在串中,逗号被切下,舍去
print(result) #黑马程序员
链式切片
在字符串处理时,可以进行切片操作的连写,被称为链式切片
如对于该字符串,有另一种思路:先反转,再取出数据
name = '万过薪月,员序程马黑,nohtyP学'
result = name[::-1][8:13:] #链式切片,先反转字符串,再取出黑马程序员
print(result)
集合
集合的定义
基本语法:
和列表、元组、字符串等定义基本相同:
- 列表使用: []
- 元组使用: ()
- 字符串使用: ""
- 集合使用: {}
当定义集合时,若有重复的元素,在定义时就会将重复的元素自动删除
集合的常用操作- 修改
首先,因为集合是无序的,所以集合不支持:下标索引访问
但是集合和列表一样,是允许修改的,所以我们来看看集合的修改方法
- 添加新元素
语法:集合.add(元素)。将指定元素,添加到集合内
结果:集合本身被修改,添加了新元素
- 移除元素
语法:集合.remove(元素),将指定元素,从集合内移除
结果:集合本身被修改,移除了元素
- 从集合中随机取出元素
语法:集合pop(),功能,从集合中随机取出一个元素
结果:会得到一个元素的结果。同时集合本身被修改,元素被移除
- 清空集合
语法: 集合.clear(),功能:清空集合
结果: 集合本身被清空
- 取出2个集合的差集
语法: 集合1.difference(集合2),功能: 取出集合1和集合2的差集 (集合1有而集合2没有的)
结果: 得到一个新集合,集合1和集合2不变
- 消除2个集合的差集
语法: 集合1.difference update(集合2)
功能: 对比集合1和集合2,在集合1内,删除和集合2相同的元素
结果: 集合1被修改,集合2不变
- 2个集合合并
语法:集合1.union(集合2)
功能: 将集合1和集合2组合成新集合
结果: 得到新集合,集合1和集合2不变
集合常用功能总结
编号 | 操作 | 说明 |
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个集合内容不变 |
8 | len(集合) | 得到一个整数,记录了集合的元素数量 |
总结
如何遍历集合元素
- 可以使用for循环进行变量。
- 不可以使用while循环,因为不支持下标索引
集合的特点:
可以容纳多个数据
可以容纳不同类型的数据 (混装 )
数据是无序存储的 (不支持下标索)
不允许重复数据存在
可以修改(增加或删除元素等)
支持for循环
字典
字典的定义
字典的定义,同样使用{},不过存储的元素是一个个的: 键值对,如下语法:
字典的key不可以重复,当key重复时,旧的key被会被新的覆盖
字典数据的获取
字典同集合一样,不可以使用下标索引
但是字典可以通过Key值来取得对应的Value
字典的嵌套
字典的Key和Value可以是任意数据类型(Key不可为字典)
那么,就表明,字典是可以嵌套的
字典的常用操作
- 新增元素
语法:字典[Key]= Value,结果: 字典被修改,新增了元素
- 更新元素
语法:字典[Key]= Value,结果: 字典被修改,元素被更新
注意: 字典Key不可以重复,所以对已存在的Key执行上述操作,就是更新Value值
stu_score ={
"王力鸿": 77"
"周杰轮": 88,
"林俊节":99
}
# 更新:王力鸿的考试成绩
stu_score['王力鸿]=100
print(stu_score) # 结果:{"王力鸿': 100,周杰轮": 88.林俊节: 99}
- 删除元素
语法:字典pop(Key),结果: 获得指定Key的Value,同时字典被修改,指定Key的数据被删除
清空字典
- 语法:字典.clear(),结果: 字典被修改,元素被清空
- 获取全部的key
语法:字典keys( ),结果: 得到字典中的全部Key
字典的常用操作总结
数据容器特点对比
数据容器可以从以下视角进行简单分类:
- 是否支持下标索引
-
- 支持: 列表、元组、字符串 - 序列类型
- 不支持: 集合、字典- 非序列类型
- 是否支持重复元素
-
- 支持: 列表、元组、字符串 - 序列类型
- 不支持: 集合、字典- 非序列类型
- 是否可以修改
-
- 支持: 列表、集合、字典
- 不支持: 元组、字符串
基于各类数据容器的特点,它们的应用场景如下
- 列表: 一批数据,可修改、可重复的存储场景
- 元组: 一批数据,不可修改、可重复的存储场景
- 字符串: 一串字符串的存储场景
- 集合: 一批数据,去重存储场景
- 字典: 一批数据,可用Key检索Value的存储场景
数据容器的通用操作- 遍历
数据容器尽管各自有各自的特点,但是它们也有通用的一些操作。
首先,在遍历上:
- 5类数据容器都支持for循环遍历
- 列表、元组、字符串支持while循环,集合、字典不支持 (无法下标索引)
尽管遍历的形式各有不同,但是,它们都支持遍历操作
数据容器的通用统计功能
除了遍历这个共性外,数据容器可以通用非常多的功能方法
容器的通用转换功能
除了下标索引这个共性外,还可以通用类型转换
其他类似
列表转成字符串:"[1,2,3,4,5]" 将整个容器转成字符串。以此类推
回头把转完的结果抄一下
容器通用排序功能
通用排序功能
sorted(容器,[reverse=True])
将给定容器进行排序
对数字按从大到小排序,对字母按顺序排序;reverse参数如果是true的话,排完的是倒序
排序排完了以后得到一个列表,此外,字典在排完序以后会丢失他的value,只留下key
容器通用功能总览
字符串比较
ASCII码
在程序中,字符串所用的所有字符如:
- 大小写英文单词
- 数字
- 特殊符号(!、\、|、@、#、空格等)
都有其对应的ASCII码表值
每一个字符都能对应上一个:数字的码值
字符串进行比较就是基于数字的码值大小进行比较的。
字符串比较
字符串是按位比较,也就是一位位进行对比,只要有一位大,那么整体就大。
字符串从左向右对于每一位进行比较,当哪个字符串先比较出较大的一位时,哪个字符串就大
函数参数
问: 如果一个函数如些两个return (如下所示),程序如何执行?
答:只执行了第一个return,原因是因为return可以退出当前函数导致return下方的代码不执行
多个返回值
如果一个函数要有多个返回值,该如何书写代码?
按照返回值的顺序,写对应顺序的多个变量接收即可
变量之间用逗号隔开
支持不同类型的数据return
函数参数种类
使用方式上的不同,函数有4中常见参数使用方式:
- 位置参数
- 关键字参数
- 缺省参数
- 不定长参数
位置参数
位置参数: 调用函数时根据函数定义的参数位置来传递参数
注意:
传递的参数和定义的参数的顺序及个数必须一致
关键字参数
关键字参数:函数调用时通过“键=值”形式传递参数
作用: 可以让函数更加清晰、容易使用,同时也清除了参数的顺序需求.
注意:
函数调用时,如果有位置参数时,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序
缺省参数
缺省参数: 缺省参数也叫默认参数,用于定义函数,为参数提供默认值,调用函数时可不传该默认参数的值(注意:所有位置参数必须出现在默认参数前,包括函数定义和调用)
作用: 当调用函数时没有传递参数,就会使用默认是用缺省参数对应的值.
注意:
函数调用时,如果为缺省参数传值则修改默认参数值,否则使用这个默认值
设置默认值时,必须在最后,即位置参数要在默认参数前
不定长参数
不定长参数: 不定长参数也叫可变参数,用于不确定调用的时候会传递多少个参数(不传参也可以)的场景
作用: 当调用函数时不确定参数个数时,可以使用不定长参数
不定长参数的类型:
- 位置传递
- 关键字传递
位置传递
注意:
传进的所有参数都会被args变量收集,它会根据传进参数的位置合并为一个元组(tuple),args是元组类型,这就是位置传递。
关键字传递
注意:
参数是“键=值”形式的形式的情况下,所有的“键=值”都会被kwargs接受,同时会根据“键=值”组成字典.
总结
- 掌握位置参数
- 根据参数位置来传递参数
- 掌握关键字参数
- 通过“键=值”形式传递参数,可以不限参数顺序
- 可以和位置参数混用,位置参数需在前
- 掌握缺省参数
- 不传递参数值时会使用默认的参数值
- 默认值的参数必须定义在最后
- 掌握不定长参数
- 位置不定长传递以*号标记一个形式参数,以元组的形式接受参数形式参数一般命名为args
- 关键字不定长传递以**号标记一个形式参数,以字典的形式接受参数,形式参数一般命名为kwargs
函数作为参数传递
在前面的函数学习中,我们一直使用的函数,都是接受数据作为参数传入:
- 数字
- 字符串
- 字典、列表、元组等
其实,我们学习的函数本身,也可以作为参数传入另一个函数内
代码如下
函数compute,作为参数,传入了test func函数中使用。
- test_func需要一个函数作为参数传入,这个函数需要接收2个数字进行计算,计算逻辑由这个被传入函数决定
- compute函数接收2个数字对其进行计算,compute函数作为参数,传递给了test func函数使用
- 最终,在test_func函数内部,由传入的compute函数,完成了对数字的计算操作
函数compute,作为参数,传入了test func函数中使用。
- test_func需要一个函数作为参数传入,这个函数需要接收2个数字进行计算,计算逻辑由这个被传入函数决定
- compute函数接收2个数字对其进行计算,compute函数作为参数,传递给了test_func函数使用
- 最终,在test func函数内部,由传入的compute函数,完成了对数字的计算操作
所以,这是一种,计算逻辑的传递,而非数据的传递。
就像上述代码那样,不仅仅是相加,相减、相除、等任何逻辑都可以自行定义并作为函数传入。
lambda匿名函数
如下图代码,我们可以:
- 通过def关键字,定义一个函数,并传入,如下图:
- 也可以通过lambda关键字,传入一个一次性使用的lambda匿名函数
使用def和使用lambda,定义的函数功能完全一致,只是lambda关键字定义的函数是匿名的,无法二次使用
文件处理
文件编码
思考: 计算机只能识别:0和1,那么我们丰富的文本文件是如何被计算机识别,并存储在硬盘中呢?
答案: 使用编码技术(密码本) 将内容翻译成0和1存入。
计算机中有许多可用编码:
- UTF-8
- GBK
- Big5
等
不同的编码,将内容翻译成二进制也是不同的。
如上,如果你给喜欢的女孩发送文件,使用编码A进行编码(内容转二进制)。
女孩使用编码B打开文件进行解码 (二进制反转回内容)
自求多福吧。
查看文件编码
我们可以使用Windows系统自带的记事本,打开文件后,即可看出文件的编码是什么:
UTF-8是目前全球通用的编码格式
除非有特殊需求,否则,一律以UTF-8格式进行文件编码即可。
总结:
- 什么是编码?
编码就是一种规则集合,记录了内容和二进制间进行相互转换的逻辑
编码有许多中,我们最常用的是UTF-8编码
- 为什么需要使用编码?
计算机只认识0和1,所以需要将内容翻译成0和1才能保存在计算机中。
同时也需要编码,将计算机保存的0和1,反向翻译回可以识别的内容。
什么是文件
内存中存放的数据在计算机关机后就会消失。要长久保存数据,就要使用硬盘、光盘、I 盘等设备。为了便于数据的管理和检索,引入了“文件”的概念。
一篇文章、一段视频、一个可执行程序,都可以被保存为一个文件,并赋予一个文件名。操作系统以文件为单位管理磁盘中的数据。一般来说,文件可分为文本文件、视频文件、音频文件、图像文件、可执行文件等多种类别。
文件操作包含的内容
在日常生活中,文件操作主要包括打开、关闭、读、写等操作。
文件的操作步骤
想想我们平常对文件的基本操作,大概可以分为三个步骤(简称文件操作三步走):
- 打开文件
- 读写文件
- 关闭文件
注意事项
注意: 可以只打开和关闭文件,不进行任何读写
open()打开函数
在Python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件,语法如下
name: 是要打开的目标文件名的字符串(可以包含文件所在的具体路径)。
mode: 设置打开文件的模式(访问模式): 只读、写入、追加等。
encoding: 编码格式(推荐使用UTF-8)
示例代码:
注意事项
注意:此时的 'f' 是open函数的文件对象,对象是Pthon中一种特殊的数据类型,拥有属性和方法,可以使用对象.属性或对象.方法对其进行访问,后续面向对象课程会给大家进行详细的介绍。
python中文件路径要用双反斜杠\\
mode常用的三种基础访问模式
事实上enconding在函数中并不是第三位,在他之前还有一个buffering=-1参数,因此这里要用关键字参数而不是位置参数
读操作相关方法
read( )方法:
readlines( )方法:
readlines可以按照行的方式把整个文件中的内容进行一次性读取,并且返回的是一个列表,其中每一行的数据为一个元素。
该处事实上不是字节,因为默认情况下是以t(文本模式)打开的,因此读取的是字符数。如果以b(二进制模式)打开,那么读取的是字节
如果在程序中多次调用read,那么下一个read会在上一个read的结尾处继续读取(读取的指针留在了上一次读取的末尾去)
readline( )方法:一次读取一行内容
for循环读取文件行
close( )关闭文件对象
time.sleep()在括号内加入要休眠的秒数可实现程序的休眠
with open 语法
操作汇总
写操作相关方法
注意:
- 直接调用write,内容并未真正写入文件,而是会积攒在程序的内存中,称之为缓冲区
- 当调用flush的时候,内容会真正写入文件
- 这样做是避免频繁的操作硬盘,导致效率下降(攒一堆,一次性写磁盘)
w模式只在第一次写入时覆盖原有内容,在后续写入时不会覆盖
写入文件使用open函数的”w”模式进行写入
写入的方法有
- wirte(),写入内容
- flush(),刷新内容到硬盘中
注意事项
- w模式,文件不存在,会创建新文件
- w模式,文件存在,会清空原有内容
- close()方法,带有flush()方法的功能
追加写入操作
注意:
a模式,文件不存在会创建文件
a模式,文件存在会在最后,追加写入文件
可以使用'\n'来写出换行符
异常
当检测到一个错误时,Python解释器就无法继续执行了,反而出现了一些错误的提示,这就是所谓的“异常”,也就是我们常说的BUG
bug单词的诞生
早期计算机采用大量继电器工作,马克二型计算机就是这样的。
1945年9月9日,下午三点,马克二型计算机无法正常工作了,技术人员试了很多办法,最后定位到第70号继电器出错。负责人哈珀观察这个出错的继电器发现一只飞娥躺在中间,已经被继电器打死。她小心地用摄子将娥子实出来,用透明胶布帖到“事件记录本”中,并注明“第一个发现虫子的实例。"自此之后,引发软件失效的缺陷,便被称为Bug.
异常演示
例如:以 'r' 方式打开一个不存在的文件
执行结果:
为什么要捕获异常
世界上没有完美的程序,任何程序在运行的过程中,都有可能出现:异常,也就是出现bug,导致程序无法完美运行下去。
我们要做的,不是力求程序完美运行
而是在力所能及的范围内,对可能出现的bug,进行提前准备、提前处理
这种行为我们称之为: 异常处理 (捕获异常)
当我们的程序遇到了BUG,那么接下来有两种情况:
- 整个程序因为一个BUG停止运行
- 对BUG进行提醒,整个程序继续运行
显然在之前的学习中,我们所有的程序遇到BUG就会出现①的这种情况,也就是整个程序直接奔溃
但是在真实工作中,我们肯定不能因为一个小的BUG就让整个程序全部奔溃,也就是我们希望的是达到②的这种情况
那这里我们就需要使用到捕获异常
捕获异常的作用在于: 提前假设某处会出现异常,做好提前准备,当真的出现异常的时候,可以有后续手段。
捕获常规异常
基本语法
快速入门
需求:尝试以'r'模式打开文件,如果文件不存在,则以'w'方式打开
捕获指定异常
基本语法
注意事项
- 如果尝试执行的代码的异常类型和要捕获的异常类型不一致,则无法捕获异常。
- 一般try下方只放一行尝试执行的代码。
e是一个对象,存储异常信息
捕获多个异常
当捕获多个异常时,可以把要捕获的异常类型的名字,放到except 后,并使用元组的方式进行书写。
执行结果:
该种方法也可以捕获所有异常
其他异常其实是基于exception构建出来的,属于他的小弟
异常else
else表示的是如果没有异常要执行的代码。
执行结果:
异常finally
finally表示的是无论是否异常都要执行的代码,例如关闭文件。
else,finally是可选的,不一定要写
异常的传递性
异常是具有传递性的
当函数func01中发生异常,并且没有捕获处理这个异常的时候,异常会传递到函数func02,当func02也没有捕获处理这个异常的时候main函数会捕获这个异常, 这就是异常的传递性
提示:
当所有函数都没有捕获异常的时候,程序就会报错
模块
什么是模块
Python 模块(Module),是一个 Python 文件,以 .py 结尾。模块能定义函数,类和变量,模块里也能包含可执行的代码。
模块的作用: python中有很多各种不同的模块,每一个模块都可以帮助我们快速的实现一些功能,比如实现和时间相关的功能就可以使用time模块。我们可以认为一个模块就是一个工具包,每一个工具包中都有各种不同的工具供我们使用进而实现各种不同的功能.
大白话: 模块就是一个Python文件,里面有类、函数、变量等,我们可以拿过来用 (导入模块去使用)
模块的导入方式
模块的导入一班放在文件开头的位置
模块在使用前需要先导入,导入的语法如下:
常用的组合形式如:
- import模块名
- from 模块名 import 类、变量、方法等
- from 模块名 import *
- import模块名as别名
- from 模块名 import 功能名 as 别名
from *表示导入模块内的全部内容
import模块名
基本语法:
案例:导入time模块
模块的本质是类,time.sleep表示层级关系,sleep这个函数是属于time这个模块内的
from 模块名 import 功能名
基本语法:
案例:导入time模块中的sleep方法
as定义别名
基本语法:
案例 :
制作自定义模块
Python中已经帮我们实现了很多的模块,不过有时候我们需要一些个性化的模块,这里就可以通过自定义模块实现,也就是自己制作一个模块
注意:
每个Python文件都可以作为一个模块,模块的名称就是文件的名称,也即是说定义模块名必须要符合标识符命名规则
注意事项:
注意事项:当导入多个模块的时候,且模块内有同名功能,当调用这个同名功能的时候,调用到的是后面导入的模块的功能
当一行语句变灰时,说明该语句没有被使用
测试模块
在实际开发中,当一个开发人员编写完一个模块后,为了让模块能够在项目中达到想要的效果,
这个开发人员会自行在py文件中添加一些测试信息,例如,在my_modulel.py文件中添加测试代码test(1,1)
问题:
此时,无论是当前文件,还是其他已经导入了该模块的文件,在运行的时候都会自动执行'test'函数的调用
解决方案:
def test(a, b):
print(a + b)
#只在当前文件中调用该函数,其他导入的文件不会调用
if __name__ == '__main__'
test (1. 1)
当在导入的模块中右键运行该文件时,if会为true,__name__会被命名为__main__,如果在导入后执行该文件,if 会为false,因此可以添加该语句后在该语句的下方添加上测试所需的代码
__all__
如果一个模块文件中有__all__变量,当使用 from xxx import *导入时,只能导入这个列表中的元素
python包
基于Python模块,我们可以在编写代码的时候,导入许多外部代码来丰富功能。
但是,如果Python的模块太多了,就可能造成一定的混乱,那么如何管理呢?
通过Python包的功能来管理
什么是python包
从物理上看, 包就是一个文件夹, 在该文件夹下包含了一个__init__.py 文件,该文件夹可用于包含多个模块文件
从逻辑上看,包的本质依然是模块
包的作用:
当我们的模块文件越来越多时,包可以帮助我们管理这些模块,包的作用就是包含多个模块,但包的本质依然是模块
有__init__.py文件就是python包,没有就是一个普通文件夹
快速入门
步骤如下:
- 新建包 my_package
- 新建包内模块: 'my_modulel' 和 'my_module2'
- 模块内代码如下
注意: 新建包后,包内部会自动创建__init__.py 文件,这个文件控制着包的导入行为
导入包
方式一:
方式二:
注意: 必须在__init__ .py 文件中添加__all__= [ ],控制允许导入的模块列表
第三方包
什么是第三方包
我们知道,包可以包含一堆的Python模块,而每个模块又内含许多的功能。
所以,我们可以认为:一个包,就是一堆同类型功能的集合体。
在Pvthon程序的生态中,有许多非常多的第三方包(非Python官方),可以极大的帮助我们提高开发效率,如:
- 科学计算中常用的: numpy包
- 数据分析中常用的: pandas包
- 人数据计算中常用的: pyspark、apache-flink包
- 图形可视化常用的: matplotlib、pyecharts
- 人工智能常用的: tensorflow
等
这些第三方的包,极大的丰富了Python的生态,提高了开发效率。
但是由于是第三方,所以Python没有内置,所以我们需要安装它们才可以导入使用哦。
安装第三方包
第三方包的安装非常简单,我们只需要使用Python内置的pip程序即可。
打开我们许久未见的:命令提示符程序,在里面输入:
pip install 包名称
即可通过网终快速安装第三方包
安装第三方包--pycharm
若想让传入的中文正确显示,可以传入ensure_ascii=false的 参数
earchar画廊,包括很多图表 Document
在用该方法之前,先要import 一个包
pos代表position:位置,pos_left,代表距离左侧距离为中,即居中显示。pos_bottom='1%',代表离底部1%
图例需要导的包:
legend_opts 图例选项
工具箱要导的包:
toolbox_opts工具箱选项
视觉映射要导的包:
visualMap_opts视觉映射选项