作用域 匿名函数 递归
函数的返回值
- 函数的返回值
a. 就是函数返回给调用者的值
b. 就是return 关键字后面的表达式的值
c. 就是函数调用表达式的值
python中每个函数都有返回值,返回值就是return后面的值, 如果函数中没有return, 那么函数的返回值就是None
函数的调用
a. 先回到函数调用的位置
b. 用实参给形参赋值(传参)
c. 执行函数体
d. 执行完函数体, 将返回值返回给函数调用表达式
e. 回到函数调用的位置
-
return关键字
a. 将return后面的值返回给函数调用表达式
b. 结束函数 -
函数的结束
a. 函数体执行完成
b. 遇到return -
函数调用表达式
python中每个函数调用表达式都是有值的
练习: 写一个函数, 判断指定的年龄是否属于成年人
def id_adult(age):
if age>18:
return True
else:
return False
def fun(n = 1, sum1 = 0):
if sum1<10000:
sum1 = sum1 + n
return fun(n+1,sum1)
else:
return n-1
print(fun())
141
作用域
- 一个变量可以使用的范围, 就是这个变量的作用域(函数和类可以影响变量的作用域)
全局变量: 从声明开始到文件结束都可以使用
局部变量: 在函数和类中声明的变量, 作用域是从声明开始到函数结束 - global和nonlocal
global: 在函数中声明一个全局变量
格式:
golbal 变量名
变量名 = 值
nonlocal: 在函数内层函数中对外层函数的变量的声明, 使得内层函数中可以使用外层函数中的变量
def func1():
a_1 = 0
print('外层',a_1)
#python中函数里面可以声明函数
def func2():
nonlocal a_1
a_1= 100
print('内层',a_1)
print('内部函数')
func2()
print(a_1)
func1()
外层 0
内层 100
内部函数
100
匿名函数
匿名函数:本质函数函数,以另外一种简单的方式来声明
匿名函数的声明:
函数名 = lambda 参数列表:返回值 ---> 结果是一个函数变量
lambda:声明匿名函数的关键字
# 写一个函数计算两个数的和
def my_sum1(x, y):
return x+y
print(my_sum1(10, 20))
# 匿名函数
my_sum2 = lambda x, y=10: x+y
print(my_sum2(10, 20))
#
funcs = []
for i in range(5):
funcs.append(lambda x: x*i)
"""
i = (0, 1, 2, 3, 4)
i = 0
[lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i,lambda x:x*i]
"""
# 4? 8?
# 6? 10?
# lambda 2:2*4
print(funcs[2](2))
print(funcs[4](2))
print(i)
30
30
8
8
4
函数作为变量
声明一个函数就是在声明一个变量
函数名可以当成变量来使用, 可以打印, 可以赋值, 可以查看类型, 可以作为函数的返回值
def fun1(a):
print(a)
return a
print(fun1, type(fun1))
#将函数fun1赋给a,这个时候a就是一个函数
a = fun1
b = fun1(10)+100
a('aaa')
#将函数fun1作为列表的元素
functions = [fun1, fun1(10)]
functions[0]('abc')
#将函数作为参数
def add(number):
sum1 = 0
for item in number:
sum1+=item
return sum1
def mul(number):
sum1 = 1
for item in number:
item *= item
return sum1
def operation(method, *number):
return method(number)
print(operation(add,4,2,5,23,5))
'''
三目运算符
c等语言中: 表达式?值1:值2
python中: 值1 if 表达式 else 值2 -> 判断表达式是否为True, 为True整个表达式的结果就是值1, 否则是值2
'''
a = 10 if 10>20 else 20
print(a)
'''
将函数作为函数的返回值
'''
# 写一个函数有一个参数,要求传入一个运算符号(+ - *)返回符号对应的功能
def fun(char):
if char == '+':
def add(*number):
sum1 = 0
for item in number:
sum1+=item
return sum1
return add
elif char == '-':
def dec(*number):
result = number(1)
if len(number)>1:
for index in range(1,len(number)):
result -= number(index)
return result
return dec
elif char == '*':
def mul(*number):
result = 1
for item in number:
result *= item
return result
return mul
else:
return lambda *number:None
print(fun('+')(2,3,4,1,5,3))
10
aaa
10
abc
39
20
18
递归
-
什么是递归
递归函数: 在函数体中调用函数本身
理论上循环能做的事情递归都能做 -
怎么写一个递归函数
a. 找临界值(跳出循环)
b. 找关系: 假设当前函数对应的功能已经实现, 找到f(n)和f(n-1)的关系
c. 使用f(n-1)与前面找到的关系去实现f(n)的功能 -
对递归的要求: 能不用就不用
函数调用的过程是一个压栈的过程(每调用一次函数, 系统都要为其分配内存空间
用来存储函数中声明变量和参数等,这个内存在调用后会自动销毁
#1+2+3+4+...+n
def fun(n):
if n>1:
return n+fun(n-1)
return 1
print(fun(100))
#2*4*6*...*n
def fun1(n):
if n>2:
return n*fun(n-2)
return 2
print(fun1(10))
def fun2(n):
if n==1:
print('*')
return
print('*' * n)
fun2(n-1)
fun2(5)
def fun3(n):
if n==1:
print('*')
return
fun3(n-1)
print('*' * n)
fun3(5)
5050
360
*****
****
***
**
*
*
**
***
****
*****
练习
1.写一个函数将一个指定的列表中的元素逆序(例如[1, 2, 3] -> [3, 2, 1])(注意:不要使用列表自带的逆序函数)
def fun(li):
for i in range(0,len(li)//2):
temp = li[i]
li[i] = li[len(li)-i-1]
li[len(li) - i - 1] = temp
li = [1,3,5,3,2,6,3,2,6]
print('逆序前:',li)
fun(li)
print('逆序后:',li)
运行结果:
逆序前: [1, 3, 5, 3, 2, 6, 3, 2, 6]
逆序后: [6, 2, 3, 6, 2, 3, 5, 3, 1]
2.写一个函数,提取出字符串中所有奇数位上的字符
def fun2(string):
li = ''
for i in range(0,len(string)):
if i % 2 == 0:
li+=string[i]
return li
string = '123456789abcdef'
print(string)
print(fun2(string))
运行结果:
123456789abcdef
13579bdf
3.写一个匿名函数,判断指定的年是否是闰年
fun3 = lambda y:'是' if (y%100!=0 and y%4==0) or y%400==0 else '不是'
n = 2016
print('%d年%s闰年'%(n,fun3(n)))
运行结果:
2016年是闰年
4.使⽤用递归打印:
n = 3的时候
@
@@@
@@@@@
n = 4的时候:
@
@@@
@@@@@
@@@@@@@
def fun4(n,k=0):
if n == 1:
print(' '*k+'@'*(2*n-1))
return
fun4(n-1,k+1)
print(' ' * k + '@' * (2 * n - 1))
fun4(4)
运行结果:
@
@@@
@@@@@
@@@@@@@
5.写函数,检查传入列表的长度,如果大于2,那么仅保留前两个长度的内容,并将新内容返回给调用者。
def fun5(li):
if len(li)>2:
return li[0:2]
return li
list1 = [1,2,3,4]
list2 = [1]
print(fun5(list1),fun5(list2))
运行结果:
[1, 2] [1]
6.写函数,利用递归获取斐波那契数列中的第 10 个数,并将该值返回给调用者。
num = {1:1,2:1}
def fun6(count):
if 0 < count < 3:
return 1
elif count>2:
result = fun6(count-1)+fun6(count-2)
num[count] = result
return result
n = 10
fun6(n)
for i in range(1, n+1):
print('斐波那契数列第%d个数是:%d'%(i,num[i]))
运行结果:
斐波那契数列第1个数是:1
斐波那契数列第2个数是:1
斐波那契数列第3个数是:2
斐波那契数列第4个数是:3
斐波那契数列第5个数是:5
斐波那契数列第6个数是:8
斐波那契数列第7个数是:13
斐波那契数列第8个数是:21
斐波那契数列第9个数是:34
斐波那契数列第10个数是:55
7.写一个函数,获取列表中的成绩的平均值,和最高分
def fun7(li):
sum1 = 0
max1 = li[0]
for item in li:
sum1 += item
if max1<item:
max1 = item
return sum1/len(li),max1
li = [77,34,76,43,78,86,88,95,43,65,76]
result = fun7(li)
print('平均值为:%.2f 最高分为:%.2f'%(result[0],result[1]))
运行结果:
平均值为:69.18 最高分为:95.00
8.写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新的列表返回给调用者
def fun8(li):
li1 = []
for index in range(0,len(li)):
if index%2!=0:
li1.append(li[index])
return li1
li = [34,'4343','gsdfg',564,'gh3456',54,'4erfgg',63,'45363456']
print(li,'\n',fun8(li))
运行结果:
[34, '4343', 'gsdfg', 564, 'gh3456', 54, '4erfgg', 63, '45363456']
['4343', 564, 54, 63]