Python基础04(函数)
python函数
1.函数类型
-
内置函数:在程序中可以直接使用
-
标准库函数:通过import语句,先导入后使用的函数
-
扩展库函数:先下载安装,再通过import语句导入后使用的函
-
用户自定义函数:本章将详细讨论函数的定义和调用方法
2.函数基本语法
def 函数名([参数列表]):
函数体
#说明:
1.函数形参不需要声明类型,根据实参的值自动推断形参的类型
2.不需要指定函数返回值类型,有return语句来确定返回值的类型
3.即使该函数不需要接收任何参数,也必须保留一对空的圆括号
4.括号后面的冒号必不可少
5.函数体相对于def关键字必须保持一定的空格缩进
6.python允许嵌套定义函数
#案例:输出小于n的斐波那契数列
def function(n):
if n < 1:
print("不存在小于1的斐波那契数")
return
a, b = 0, 1
while a < n:
print(a, end=" ")
a, b = b, a + b
function(10)#调用函数
3.函数的参数
1.函数形参不需要声明类型,也不需要指定函数返回值类型
2.定义函数时不需要声明参数类型,解释器会根据实参的类型自动推断形参类型。
3.几种传参方式:
方式一:位置参数
#位置参数是比较常用的形式,调用函数时实参必须和形参在顺序、个数和类型上一一匹配。
>>> def demo(a, b, c):
print(a, b, c)
>>> demo(3, 4, 5) #按位置传递参数
3 4 5
方法二:关键字参数
#当实参作为关键参数被传递是通过name=value的形式传递每个参数,是调用函数时的参数传递方式,与函数定义无关。通过关键参数可按参数名字传递值,明确指定哪个值传递给哪个参数,实参顺序可以和形参顺序不一致,但不影响参数值的传递结果
>>> def demo(a, b, c):
print(a, b, c)
>>> demo(c=8, a=9, b=0)
9 0 8
方法三:默认值参数
注意:函数定义时是可以混用默认值参数和非默认值参数的,但混用时非默认值参数必须定义在默认值参数之前,默认参数之后没有形参。
def 函数名(……,形参名=默认值):
函数体
方法四:可变长度参数
1)一个星号的形参:
用来接收多个位置参数并将其放在一个元组中
>>> def demo(*p):
print(p)
>>> demo(1,2,3)
(1, 2, 3)
2)两个星号的形参:
用来接收多个关键参数并存放到字典中
def demo(**p):
for item in p.items():
print(item)
>>> demo(x=1,y=2,z=3)
(‘x’, 1)
(‘y’, 2)
('z', 3)
3)传递参数时,序列解包
把序列中的各个元素依次赋值给每个变量,称为序列解包。在函数由实参向形参的传递时,可以通过在实参序列前加一个星号将其解包,然后传递给多个单变量形参
def demo(a, b, c):
print(a + b + c)
# 对列表进行解包
aList = [1, 2, 3]
demo(*aList)
# 对元组进行解包
aTuple = (1, 2, 3)
demo(*aTuple)
# 对字典的键进行解包
aDict = {1: 'a', 2: 'b', 3: 'c'}
demo(*aDict)
如果函数实参是字典,可以在前面加两个星号进行解包,等价于关键参数。此时的实参名必须与形参名相对于,或者用**p接受参数
def demo(a, b, c):
print(a + b + c)
#相当于关键参数传递
aDict = {'a': 1, 'b': 2, 'c': 3}
demo(**aDict)
demo(*aDict.values())
4.变量作用域
- 变量起作用的代码范围称为变量的作用域,不同作用域内变量名可以相同,互不影响。
- 局部变量
1.在函数内部定义的普通变量只在函数内部起作用,称为局部变量。当函数执行结束后,局部变量自动删除,不再可以使用。
2.局部变量的引用比全局变量速度快,应优先考虑使用。
def demo():
x = 1 # 局部变量
print(x)
demo()
print(x) # NameError: name 'x' is not defined
- 全局变量:可以通过关键字global来定义。这分为两种情况:
x = 1 # 全局变量
def demo():
print(x)
demo()
x = 1 # 全局变量
def demo():
x = 2 # 局部变量
print(x)
demo()#2
print(x)#1
函数内对全局变量的操作
1.一个变量已在函数外定义,如果在函数内需要为这个变量赋值,并要将这个赋值结果反映到函数外,可以在函数内使用global将其声明为全局变量。
x = 1 # 全局变量
def demo():
global x# 全局变量
x = 2
print(x)
demo() # 2
print(x) # 2
2.如果一个变量在函数外没有定义,在函数内部也可以直接将一个变量定义为全局变量,该函数执行后,将增加一个新的全局变量
def demo():
global x# 全局变量
x = 2
print(x)
demo() # 2
print(x) # 2
如果局部变量与全局变量具有相同的名字,那么该局部变量会在自己的作用域内隐藏同名的全局变量。
def demo():
x = 2
print(x)
x = 3
demo() # 2
5.lambda表达式
-
lambda表达式可以用来声明匿名函数,也就是没有函数名字的临时使用的小函数,尤其适合需要一个函数作为另一个函数参数的场合。也可以定义具名函数。
-
lambda表达式只可以包含一个表达式,该表达式的计算结果可以看作是函数的返回值,不允许包含复合语句,但在表达式中可以调用其他函数。
-
格式:
lambda arguments: expression
-lambda 是关键字,用来定义匿名函数。
-arguments 是传递给匿名函数的参数,多个参数可以用逗号分隔。
-expression 是匿名函数的返回值。expression 只能是一个表达式,不能包含多个语句。
# 一个三个数相加的lambda表达式
f = lambda x, y, z: x + y + z
print(f(1, 2, 3))
# 返回使得列表中每个数加10的新列表结果
aList = [1, 2, 3, 4, 5]
print(list(map(lambda x: x + 10, aList)))
# 排序
aList = list(range(20))
from random import shuffle
shuffle(aList)
# 按字符串规则排序
aList.sort(key=lambda x: str(x))
print(aList)
6.生成器函数
#包含yield语句的函数可以用来创建生成器对象,这样的函数也称生成器函数。
1.yield语句与return语句的作用相似,都是用来从函数中返回值。与return语句不同的是,return语句一旦执行会立刻结束函数的运行,而每次执行到yield语句返回一个值之后会暂停或挂起后面代码的执行,下次通过生成器对象的__next__()方法、内置函数next()、for循环遍历生成器对象元素或其他方式显式“索要”数据时恢复执行。
2.生成器具有惰性求值的特点,适合大数据处理
# 案例:输出前10个的斐波那契数列
def function():
a, b = 0, 1
while True:
yield a
a, b = b, a + b
x = function()
for i in range(10):
print(next(x), end="\t")#或者print(x.__next__(), end="\t")