Day13:函数(2)--匿名函数、闭包

作业讲解

  • (面试题:考算法)自定义一个函数将传入的两个有序列表[1,5,7,9]和[2,2,6,8]合并一个有序列表,比如:[1,2,2,3,6,7,8,9]
    • 本题尽量不要使用sort,两层循环效率比较低
      使用一层循环
  • 斐波那契数列列指的是这样⼀一个数列列:1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …;
    这个数列列从第三项开始,每⼀一项都等于前两项之和。写⼀一个函数,传 ⼊入项数n,返回第n项的值
# 斐波那契数列的解法,更简明
def fibanacci(n):
    pre = next = 1
    for x in range(3, n+1):
        res = pre + next
        pre, next = next, res
    return  res

print(fibanacci(11))

函数类型

  • 函数名是变量,变量是保存对象地址的,有对象必有类。自定义一个函数add(x,y),add(x,y)是一个函数对象(源自函数类型),add则是变量名,指向该函数对象的地址。
  • 普通对象是放在内存的堆区,函数是放在代码区

匿名函数 lamba

a = lambda x,y:x+y

特点:

  • lambda只是一个表达式,函数体比def定义的简单得多
  • lambda的函数体不是代码块,而是一个表达式
  • lambda只有一行,运行效率很高

传入函数

一个函数可以接受另外一个函数作为参数,这种函数就称之为高阶函数或传入函数。主要用于实现通用编程,排序等复杂功能。
需求:
计算偶数、奇数、能被7和5整除的数的和等等,如何用一个函数解决?
分析:
定义函数方法求。例如:
求偶数和方法如下:

def even(n):
	total = 0
	for i in range(0,n+1):
		if i%2 == 0:
			total += i
	return total
	

求奇数和的函数定义也同上,只是将if语句修改成if i%2 != 0;
求被3整除的数的和也类似。
能否在函数的基础上,通过某个方法对符合条件的数进行累加?
思路就是用一个函数来判断传入的参数是否满足条件,如果满足条件就传入。
例如:

def sum1(n,callback):
	total = 0
	for i in range(0,n+1):
		if callback(i):          # 如果符合条件,条件由callback负责,callback(i)必须要有一个参数
			total += i
	return total
sum1(100,lambda x:x%2==0)

排序例子:
基本算法是冒泡算法,对列表元素依次进行比较,通过交换将大的数字放在最右边。
原有函数方法的缺点是不够通用,因为当列表元素是字典时就不能实现了。
解决思路依然是传入函数,即将过滤函数作为参数

def mySort2(list,func):
    for j in range(len(list)-1):
        for i in range(len(list)-1-j):
            if func(list[i]) > func(list[i+1]): #
                list[i], list[i+1] = list[i+1], list[i]
    return list
print(mySort2(list2,lambda value:value['age']))

闭包

def outer():
	a = 10
	def inner():  
		# a += 5    # 不可以修改外部变量
		print(a)    # 闭包特征1、在内部函数使用外部函数的变量
	return inner    # 闭包特征2、在外部函数返回内部函数的函数名

一般情况下,如果一个函数结束,函数的内部所有东西都会释放掉,局部变量量都会消失。但是闭包是一种特殊情况,如果外函数在结束的时候发现有自己的局部变量将来会在内部函数中用到,就把这个局部变量量绑定给了了内部函数,然后自己再结束。

在闭包中⽆无法直接修改外部变量量x的值

变量作用域

# 内建作用域 在所有代码中都可用  max int()
# 全局作用域: 从定义开始,到本文件结束
```py
a = 2
def outter(a):
    print(a)
    a = 9       # 闭包作用域 从定义开始到外部函数结束
    print(a)
    b = 90
    def inner():
        a = 20    # 局部作用域: 从定义开始到本函数结束
        print(a)
    inner()
    # outter(10)
	# print(a)

	# 变量作用域的查找: 从下往上查找(从里往外),找离它最近的定义(不能往函数里找)

在python中,只有函数/类/模块才引⼊入作⽤用域,
if/elif/else , while/for,try/except等并不不会引⼊入新的作⽤用域

#if语句句不不引⼊入新作⽤用域,msg在外⾯面可以使⽤用
if True:
	msg = "message"
	print(msg)

在Python中,当内部作⽤用域想修改全局变量量的时候,则就要使⽤用global关键字进⾏行行
声明

如果要修改函数作⽤用域中的变量量,则使⽤用nonlocal
需要明确的是,nonlocal关键字定义在闭包⾥里里⾯面

一般规则:尽量不要在函数里直接使用全局变量

作业

# 函数填空题
# 1. 函数定义
def test1(a,b):
	return a + b
# 则test1(3,b=5)的值为_________;test1(b=10,a=2)的值为
# _________。(8,12)
# 2. 函数定义:
def test(a,b=2,*args):
	return a + b + sum(args)
#则test(1,2,3,4,5)的值为___________;test(1)的值为:
#___________;test(*[3,2,1,5])的值为:________;
#test(*{1:2,3:4,5:6}.values())的值为_______。(15,3,11,12)
# 3. 函数定义:
def test(*args, **kwargs):
	tmp = list(args) + list(kwargs.values())
	return sum([tmp[x] for x in range(len(tmp) if not
(x % 2) )]
# 则test(a = 3 , b = 4 , c = 5 ) 的值:_ _ _ _ _ _ ;
# test(**{1:2,3:4,5:6,7:8})的值为:_________;
# test(1,3,5,7,a=10,b=3)的值为:_________。(8,8,16)
# 4. 函数定义:
def link(*args):
	args = [x if isinstance(x,str) else str(x) for x in
args]
	return ‘’.join(args)
# 则lin k (1 ,2 ,3 ) 的值为:________ ;lin k (‘ 北
# 京’,’python’,’1902’)的值为__________。("123","北京python1902")
# 5. 函数定义:
def demo(*args):
	return args * 2
# 则sum(demo(1,2,3))的值为________;len(demo())等于
_________。(12,0)
6. 函数定义为:
def judge(a):
	if a > 0:
	return True
# 则print(“兔⼦” if judge(-1) else ‘狗’)输出:_______('狗')
7. 已知:pf = lambda a,b=2:a + b; 则pf(2) = ______;
pf(3,4) = ______; pf(b=3,a=5) = _________;(4788. 已知:
def demo(a):
	a = 5
则执⾏a = 10; demo(a);后a = 10_____;
9. 已知:
def demo(a):
	for key in a:
	a[key] += 10
# 则a = {1:10,2:20,3:30};则执⾏demo(a)后,a =
# _______________。
# {1:20,2:30,3:40}

for i in dict时,遍历的是key

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值