Python基础语法详解(进阶篇)
Python基础语法(3)
函数
在我们有了之前的语法基础之后,现在我们来认识一下Python中的函数
在数学中,我们有各种的函数,而编程语言中的函数和数学中的函数不太一样
什么是函数
简单来说,在编程语言中的函数,就是一段封装好的,可以反复使用的代码
比如我们需要实现一个两个数相加的功能,这时候,我们有几组数据,那可能需要写几次相加的代码,但是我们如果写好了一个相加函数,那么每次我们只需要在需要加的时候调用这个函数就好了
#计算下面几组数据的和
# 12 56
# 33 45
# 42 67
#方法一:一个个写
a = 12
b = 56
the_sum = a + b
print(the_sum)
a = 33
b = 45
the_sum = a + b
print(the_sum)
a = 42
b = 67
the_sum = a + b
print(the_sum)
# 方法二:函数
def the_sum(a,b)
return a+b
print(the_sum(12,56))
print(the_sum(33,45))
print(the_sum(42,67))
我们可以对比一下,使用函数和不使用函数,无论是在代码量和后期的代码管理上来看,都是前者都是更好的
函数的定义和调用
定义
那么我们该如何定义一个函数呢
# 函数定义的语法规则
def 函数名(形参列表):
函数体
return 返回值
首先,我们需要用def来声明一下,接下来我们定义的是一个函数,如何函数名(命名规则和变量名的规则一样)
之后括号里面就是我们的参数,可以是一个或者多个,后面用冒号(英文)表示结束
下面用一个缩进表示函数体,也就是这函数内部实现功能的代码
最后某些函数可能需要有返回值,也有函数只要实现功能就好了不需要返回值,所以这个return按需取舍
调用
那我们定义好了一个函数,怎么来调用它呢
# 调用函数
#对于没有返回值的函数
函数名(实参列表)
#对于有返回值的函数,我们可以用一个变量来接受这个返回值
变量=函数名(实参列表)
这里和c++/java不同的是,Python中的函数参数,没有严格的类型匹配要求(只要函数体内的操作支持接收的类型就行)
函数的实参,形参,返回值
实参和形参
在我们调用一个函数的时候,我们在()中所写的参数就是实参
顾名思义也就是我们用函数解决问题的时候,实际需要具体值
我们在定义函数的时候()里的参数,我们把它们叫作形式参数
也就是配合我们实现功能的,具体是什么值,需要我们赋予它
# 例如下面我们来实现一个加法函数
def add(x,y):# 这里的x,y就是形式参数
return x,y
a=10
b=20
print(add(a,b))#这里的a,b就是实际参数
这里有几点我们需要注意一下
①实参和形参本质上不是同一个东西,之前我们说过,变量的创建,实际上是在内存中开辟了一块空间
而形参其实是再开辟了一块空间,然后将实参的值,拷贝了一份过来,也就是说对于形参进行一些改变操作,对于实参是不会有影响的
#我们可以写一下交换函数
#再函数里,交换形参的值,看看实参的值是否交换
def change(x,y):
z=x
x=y
y=x
a=1
b=2
change(a,b)
print(a,b)
a,b的值并没有交换
②形参和实参的变量名可以用一样的
③我们在定义函数的时候,可以给形参一个默认值,我们会将有默认值的参数写在后面
def add(x,y,debug=False):
if debug:
print(x,y)
print(x+y)
a=10
b=20
add(a,b)#可以不传debug
print("----------")
add(a,b,True)#也可以传debug,用来实现更多需求
④我们在进行传参的时候,默认是按位置传递的,也就是顺序传递,当然我们也可以在实参前加上关键字,就可以不按位置传递
def add(x,y):
print(x,y)
add(y=10,x=20)#这样也可以实现参数的传递
顺序传递和关键字传递可以混用,但是关键字传递要写在顺序传递之后哦
返回值
对于返回值,我们来讲几个特别的用法
①多元赋值
我们有时候可能需要返回两个值,例如坐标,这时候,可以用多元赋值的方法来接收返回值
def add(x,y):
return x,y
a,b = add(10.20)
#如果我们只想接收其中一个,可以用_来进行占位
_,c = add(12.23)
②链式调用
链式调用是用第一个函数的返回值,作为第二个函数的参数,本质上是一种嵌套
#我们最常见的打印一个求和函数的值就是链式调用
def add(x,y):
return x+y
print(add(10,20))#用求和函数返回的和,来作为打印函数要打印的对象
这里说明一下,因为每调用一个函数,就需要在内存中开辟出它的函数栈帧(空间),所以我们嵌套的层数不能太多哦
函数变量的作用域
我们在函数内部创建出来的变量,只能作用于这个函数内部,出了函数,它的空间就会释放,也就不存在了
def add(x,y):
z=x+y
add(10,20)
print(z) #像这样就会报错
如果我们想让函数内部创建的变量在外面也能被使用,我们可以用global
来声明一下,这样z就成为全局变量了
def add(x,y):
global z
z = x+y
add(10,20)
print(z) #像这样就不会报错
同样的,如果在函数内部创建了一个和外面同名的变量,那么函数里面使用的,还是函数内部创建的变量
def test():
x=10
print(f"内{x}")
x=20
test()
print(f"外{x}")
当然,我们可以直接在函数中使用已经创建好的全局变量
def test():
print(x)
x=10
函数递归
递归,就是函数自己调用自己,通常我们需要解决一个大问题的时候,可以把他转化成一些子问题,这时候可能就需要递归
我们用一个求阶乘的问题来举例
# 我们求一个n的阶乘,这时候,就可以把他转换为先求n-1的阶乘,于此类推的子问题
def jiecheng(n):
if n==1:
return 1
return n*jiecheng(n-1)
print(jiecheng(5))
对于递归,我们有几个需要注意的地方
①要有一个递出条件,如上面的n==1,就是当我们化到求1的阶乘时,直接返回1
②每递归一次们都需要不断接近递出条件,如上面的函数,每次递归,n都是不断接近1的
③可以用递归解决的问题,我们都可以化为相同的循环代码来解决,递归太深可能会使栈溢出,所以我们要更具实际情况来决定该怎么解决问题
列表和元组
列表
很多时候,我们需要存一系列数据,如:一个班所有人的成绩,这时候我们如果创建一个个变量,就会特别的麻烦
于是,在Python中,我们列表,可以用一个变量来表示多个数据,它就类似于C++中的数组
列表的创建
# 我们有两种方式可以创建一个列表
a = []
b = list()
#上述两种方式都是创建了一个空的列表
#我们可以看看它们的类型
print(type(a))
print(type(b))
这里可以看到,是列表(list)类型,它是Python的一个内置类型
当然我们可以在创建的时候,让它存一些值
a = [1,2,3,"hello"]
#这里和数组不一样的是,列表存的值,可以是不同类型的,两个元素之间用,隔开
#我们可以打印看看
print(a)
列表的访问和修改
#这里我们通过[]这个下标访问操作符来访问列表
# 先创建一个元素
a = [1,2,3,4]
#我们来访问下标为1的元素
print(a[1])
#在列表后面加上[],在[]中填写我们想访问的下标即可
这里我们发现的打印的是2,其实列表和C++的数组一样,下标都是从0开始的
#同时我们也可以用[]对列表元素进行修改
a = [1,2,3,4]
a[0] = 5
print(a)
其中我们[ ]中的数字可以写成负数
a = [1,2,3,4]
print(a[-1])
这里我们可以看到访问4这个元素,其实写成-1,就相当于访问列表倒数第一个元素
这里我们需要注意,我们写的下标一定要在有效范围之中哦
列表的切片操作
所谓的切片操作,就是截取列表中的一部分,取它的一个子列表
a = [1,2,3,4]
print(a[1:3])#这里我们用 列表名[前边界:后边界] 这样的格式来对列表进行切片
#其中切片的下标范围是[前边界,后边界)
#前后边界都可以省略,省略默认就是到最前或者最后了
print(a[1:])
print(a[:3])
print(a[:])
同时,我们还可以指定切片的步长
a = [1,2,3,4,5,6,7,8,9]
print(a[::2])#这样就是从第一个元素开始,每两个元素取一个
#步长为负数的话就是从后向前
print(a[::-1])
这里注意,我们切片的时候,如果输入的下标超出范围不会抛出异常,而是会尽可能的去取
列表的遍历
遍历,就是把每个元素取出来,并进行操作,一般搭配循环
之前我们有个len()
这个函数,它也可以来求列表的长度
# 这里我们用两种方法来遍历列表
a = [1,2,3,4,5]
#第一种,直接取出列表中的值给一个变量
for elem in a:#之前我们说过,in后要是一个可迭代对象,我们的列表就是
print(elem)
print("-------")
#第二种,通过下标遍历
for i in range(0,len(a)):
print(a[i])
#这两种方法的不同在于,第一种对于elem操作,并不会影响a的元素
#第二种,可以对a中的元素进行修改
列表的插入(append,insert)
#如果我们想在列表的后面加上一个元素的话
#可以通过append()这个函数来进行
a = [1,2,3,4,5]
a.append("hello")#我们在后面插入一个hello
print(a)
#如果我们想在任意位置插入一个元素
#可以使用insert()
a = [1,2,3,4,5]
a.insert(1,"hello")#这样就是在下标为1的位置插入hello
print(a)
#当然如果我们给出一个超范围的下标,会直接插在第一个或者最后一个
像上面这两个函数,需要搭配对象来使用的,我们叫它们方法
列表元素的查找(in,index)
a = [1,2,3,4]
#我们会用in来判断一个元素在不在列表中
print(1 in a)#这段代码的含义是,1在不在a中,在返回True,不存在返回False
print(1 not in a)# 1 是否不存在a中
#此外,如果我们想查询元素的下表可以使用index()
a = [1,2,3,4]
print(a.index(2))#2在不在a中,在返回下标,不在抛出异常
列表元素的删除(pop,remove)
这里我们介绍三种删除
# 尾删
a = [1,2,3,4]
a.pop()#直接删除最后一个元素
print(a)
#按下标删
a = [1,2,3,4]
a.pop(1)#删除下标为1的元素
print(a)
#按值删除
a = ["aa","bb","cc"]
a.remove("bb")#删除列表中的bb
print(a)
列表的拼接(+,extend,+=)
类似于字符串,我们的列表也是可以进行拼接的,这里我们介绍三种拼接方式
#使用+拼接
a = [1,2]
b = [3,4]
c = b + a
print(c)
#这种拼接方式不会对a,b造成什么影响
#使用extend拼接
a = [1,2]
b = [3,4]
a.extend(b)#把b接到a的后面
#我们来看看这时候a和b
print(a)
print(b)
这时候发现,对a列表还是有影响的
#使用+=
a = [1,2]
b = [3,4]
a += b #效果类似于第二种
print(a)
元组
元组,和列表一样,也是来存储多个数据的,包括它的操作都和列表一样
不一样的是元组是不可变的,就是我们不能对元组中的元素进行改变
元组的创建
和列表一样,元组也有两种创建方式
#我们用()来表示一个空元组
a = ()
b = tuple()
#我们看看它的类型
print(type(a))
print(type(b))
#同样,我们也可以在创建的时候存元素进去
元组中的操作
元组是不可变的,所以列表中的extend append pop
这些对元组有影响的操作是不可以的
其他操作和列表一样
这里注意,拼接中的+可以使用哦
字典
字典是一个用来存键值对的数据结构
什么是键值对呢,目前我的理解来说,就是两个相互联系数据,一个做键:key,一个做值:value;通过键可以立马找到值,就像每个人的学号一样
字典中可以同时包含多个键值对,但是要求键(key)是不能重复的
字典的创建
# 这里我们还是有两种方式创建字典
a = {}
b = dict()
#我们来看看它的类型
print(type(a))
print(type(b))
#这里我们看看怎么在创建的时候存键值对
a = {"id":1,"name":"zhangsan"}#我们还是用逗号区分元素,每个元素前面写key,后面写value,中间用:分开
#但是我们为了更好地观察元素一般这样写
a = {
"id":1,
"name":"zhangsan",#这里的逗号可有可无
}
print(a)
这里的key类型是有限制的,而value是任意类型的哦
字典中的查找操作
这里我们介绍两种查找
#查找key
a = {
"id":1,
"name":"zhangsan",
}
print("id" in a) #id是否在字典a的key中,在返回True,不存在返回False
#根据key获取value
a = {
"id":1,
"name":"zhangsan",
}
print(a["id"])#[]中写key,获取对应的value,输入无效key会抛出异常
这里博主觉得,有点像把列表的下标换成其他类型的,不是0,1,2,3了
字典元素的增加和修改
a = {
"id":1,
"name":"zhangsan",
}
#我们用[]进行新增元素
a["score"] = 90 # []中写key,=后面写对应的value
print(a)
#我们还是用[]进行修改
a["score"] = 100
print(a)
#对于没有的键值对是新建
#对于有的键值对是修改
字典元素的删除
a = {
"id":1,
"name":"zhangsan",
}
#我们用pop进行删除
a.pop("name")#()中写key,就可以删除对应的键值对
print(a)
字典的遍历
字典的遍历有很多方法
#我们先说最常见的for遍历
a = {
"id":1,
"name":"zhangsan",
"score":100
}
for key in a:
print(key,a[key])#类似列表,我们一样可以用for来遍历字典的键和值,同样字典也是可迭代对象
#但是我们只能获取key,之后再根据key访问到value
#用keys获取字典中所有的key#用keys获取字典中所有的key
a = {
"id":1,
"name":"zhangsan",
"score":100
}
print(a.keys())
这里我们发现出来一个类似于列表的数据
#我们来看看它的类型
a = {
"id":1,
"name":"zhangsan",
"score":100
}
print(type(a.keys()))
#其实我们就要可以把他当作列表那样取操作
for elem in a.keys():
print(elem)
下面的values和它一样
#用values获取字典中所有的value
a = {
"id":1,
"name":"zhangsan",
"score":100
}
print(a.values())
但是下面就有点不一样了
#用items获取字典中所有的键值对
a = {
"id":1,
"name":"zhangsan",
"score":100
}
print(a.items())
可以发现出来一个类似列表里每个元素是元组的数据
其实我们同样可以把他当作列表操作
a = {
"id":1,
"name":"zhangsan",
"score":100
}
#但是对于每个元素,我们需要按多元赋值来
for key,value in a.items():
print(key,value)
合法key的类型
之前我们说过key的类型是有要求的
对应key来说,它需要是一个可哈希的类型
直白点来说就是,key需要是一个不可变的类型
在Python中我们常见的整数,字符串,浮点数…这些基本数据类型都是不可变的,包括元组,他们都可以作为key的类型
那么有哪些不能呢:列表,字典…这些都不可以(更多的可以关注Python文档)
总结
这一部分,我们介绍了函数,列表,元组,字典,对Python有了更多的认识,其中博主认为,后三者有相似的地方,可以关联记忆
如果大家有什么建议和补充,欢迎评论留言
作者:Emilia486.