作用域 匿名函数 递归

函数的返回值

  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]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352