作用域 匿名函数 递归

2018-07-25  本文已影响0人  pubalabala

函数的返回值

  1. 函数的返回值
    a. 就是函数返回给调用者的值
    b. 就是return 关键字后面的表达式的值
    c. 就是函数调用表达式的值

python中每个函数都有返回值,返回值就是return后面的值, 如果函数中没有return, 那么函数的返回值就是None

函数的调用
a. 先回到函数调用的位置
b. 用实参给形参赋值(传参)
c. 执行函数体
d. 执行完函数体, 将返回值返回给函数调用表达式
e. 回到函数调用的位置

  1. return关键字
    a. 将return后面的值返回给函数调用表达式
    b. 结束函数

  2. 函数的结束
    a. 函数体执行完成
    b. 遇到return

  3. 函数调用表达式
    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

作用域

  1. 一个变量可以使用的范围, 就是这个变量的作用域(函数和类可以影响变量的作用域)
    全局变量: 从声明开始到文件结束都可以使用
    局部变量: 在函数和类中声明的变量, 作用域是从声明开始到函数结束
  2. 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

递归

  1. 什么是递归
    递归函数: 在函数体中调用函数本身
    理论上循环能做的事情递归都能做

  2. 怎么写一个递归函数
    a. 找临界值(跳出循环)
    b. 找关系: 假设当前函数对应的功能已经实现, 找到f(n)和f(n-1)的关系
    c. 使用f(n-1)与前面找到的关系去实现f(n)的功能

  3. 对递归的要求: 能不用就不用
    函数调用的过程是一个压栈的过程(每调用一次函数, 系统都要为其分配内存空间
    用来存储函数中声明变量和参数等,这个内存在调用后会自动销毁

#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]
上一篇下一篇

猜你喜欢

热点阅读