20~22 函数(下)

 20 函数:内嵌函数和闭包



一、内嵌函数

>>> def fun1():
	print('fun1()正在被调用...')
	def fun2():
		print('fun2()正在被调用...')
	fun2()

>>> fun1()
fun1()正在被调用...
fun2()正在被调用...

 【注意①】内嵌函数只能在外部函数的范围内起作用!

 【容易错误】

>>> def fun1():
	print('fun1()正在被调用...')
	def fun2():
		print('fun2()正在被调用...')


>>> fun1()
fun1()正在被调用...

二、闭包  __ 
        如果在一个内部函数里,对外部函数的作用域内(但不是在全局作用域)的变量进行引用,那么这个内部函数就被认为是闭包。
        就是能够读取其他函数内部变量的函数。

>>> def FunX(x):     #定义FunX()的范围就是外部作用域,x就是外部作用域的变量
	def FunY(y):     #FunY()就是FunX()的内部函数
		return x * y #FunY()对x进行引用
	return FunY      '''达到以上三点要求,FunY()就是个闭包'''

【易错】内部函数返回值不要写【FunY()】,否则: 

>>> def FunX(x):
	def FunY(y):
		return x * y
	return FunY()

>>> FunX(2)(3)
Traceback (most recent call last):
  File "<pyshell#17>", line 1, in <module>
    FunX(2)(3)
  File "<pyshell#16>", line 4, in FunX
    return FunY()
TypeError: FunY() missing 1 required positional argument: 'y'

来试一下: 

>>> i = FunX(8)
>>> i
<function FunX.<locals>.FunY at 0x0000021F59727F28>
>>> type(i)
<class 'function'>

>>> i(5)
40
>>> FunX(8)(5)
40

【注意】但是不可以在外部函数的外边对内部函数进行调用:

>>> FunY(5)
Traceback (most recent call last):
  File "<pyshell#48>", line 1, in <module>
    FunY(5)
NameError: name 'FunY' is not defined

【注意】在内部函数中,只能对外部函数进行调用,不可以进行修改:

>>> def Fun1():
	x = 5
    def Fun2():
        x *= x
	   	return x
    return Fun2()

>>> Fun1()
Traceback (most recent call last):
  File "<pyshell#60>", line 1, in <module>
    Fun1()
  File "<pyshell#59>", line 6, in Fun1
    return Fun2()
  File "<pyshell#59>", line 4, in Fun2
    x *= x
UnboundLocalError: local variable 'x' referenced before assignment

【错误原因】对于【Fun2()】,【x = 5】是外部的变量,而在【Fun2()】内的【x *= x】是
                      试图改变外部的变量【x】的值,肯定就是不行的。


【解决办法①】变成列表,可变对象(进行容器改造)

>>> def Fun1():
	x = [5]
	def Fun2():
		x[0] *= x[0]
		return x[0]
	return Fun2()

>>> Fun1()
25

【解释】当将【x = 5】变成列表【x = [5]】时,【x】的值就不是储存在【Fun2()】的外部函数中了。此时【x】可变,因为是列表。


【解决办法②】用关键字【nonlocal】将【x】升级成非局部变量

>>> def Fun1():
	x = 5
	def Fun2():
		nonlocal x
		x *= x
		return x
	return Fun2()

>>> Fun1()
25

21 函数:lambda表达式



【原语句①】

>>> def ds(x):
	return 2 * x + 1

>>> ds(5)
11

【lambda语句①】

>>> lambda x : 2 * x + 1
<function <lambda> at 0x000001C7D0A078C8>

>>> ds = lambda x : 2 * x + 1
>>> ds(5)
11

【原语句②】

>>> def add(x, y):
	return x + y

>>> add(3, 4)
7

【lambda语句②】

>>> lambda x, y : x + y
<function <lambda> at 0x000001C7D0A07C80>

>>> a = lambda x, y : x + y
>>> a(3, 4)
7

一、lambda表达式的作用

        1.python写一些执行脚本时,使用lambda就可以省下定义函数的过程,比如说我们只是需要写个简单的脚本来管理服务器时间,我们就不需要专门定义一个函数然后再写调用,使用lambda就可以使得代码更加精简。
        2.对于一些比较抽象并且整个程序执行下来只需要调用一两次的函数,有时候给函数起个名字也是比较头疼的问题,使用lambda就不需要考虑命名的问题了。
       3. 简化代码的可读性,由于普通的屌丝函数阅读经常要调到开头的def定义部分,使用lambda函数可以省去这样的麻烦



二、两个比较牛逼的BIF(内置函数)


(一)filter()  __过滤器

    1、两个参数,(function or None, iterable)

        有两个参数,第二个参数为可迭代的数据,第一个参数可以为None或者函数,当为None时,将iterable中为真的数据挑选出来,当为function时,将iterable中满足function的结果为真的数据挑选出来。
        1)当(None, iterable)时,过滤掉【iterable】中的【非True】内容:

>>> filter(None, [1, 0, False, True])
<filter object at 0x000001C7D0A13CF8>

>>> list(filter(None, [1, 0, False, True]))
[1, True]

         2)当(function, iterable)时,过滤掉【iterable】中【function的结果为0】的内容:

>>> def odd(x):
	return x % 2

>>> temp = range(10)
>>> show = filter (odd, temp)
>>> list(show)
[1, 3, 5, 7, 9]

   2、filter() 与 lambda结合:

>>> list(filter(lambda x : x % 2, range(10)))
[1, 3, 5, 7, 9]

(二)map()  __映射

    两个参数,(function, *iterable),直接代很多数计算(lambda进化版)

        将可迭代序列的每一个数据作为函数的参数进行运算加工,直到可迭代序列的每一个元素都加工完毕,返回所有加工后的元素构成的新序列。

>>> list(map(lambda x : x * 2, range(10)))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

22 函数:递归是神马

        普通程序员用迭代,高级程序员用递归!~

>>> def recursion():
	return recursion()

>>> recursion()
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    recursion()
  File "<pyshell#3>", line 2, in recursion
    return recursion()
  File "<pyshell#3>", line 2, in recursion
    return recursion()
  File "<pyshell#3>", line 2, in recursion
    return recursion()
  [Previous line repeated 990 more times]
RecursionError: maximum recursion depth exceeded

Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    recursion()
  File "<pyshell#3>", line 2, in recursion
    return recursion()
  File "<pyshell#3>", line 2, in recursion
    return recursion()
  File "<pyshell#3>", line 2, in recursion
    return recursion()
  [Previous line repeated 990 more times]
RecursionError: maximum recursion depth exceeded

无限循环,直接干掉python,可以设置一下递归的深度(100000层):

>>> import sys
>>> sys.setrecursionlimit(100000)

不开玩笑了,进入正题。举个正常的例子:

   (一)递归求阶乘:写一个求阶乘的函数:

        正整数阶乘,如【5!】,就是【1*2*3*4*5】,为【120】。即【120是5的阶乘】


非递归方法

def factorial(n):
    result = n
    for i in range(1, n):
        result *= i

    return result

def factorial(n):
    result = 1
    for i in range(1, n + 1):
        result *= i

    return result

【代码解读】标红为【result = n】或【result = 1
        __对于输入【n】,有【result = n × 1 × 2 × ... × (n-1)】
        __对于输入【n】,有【result = 1 × 1 × 2 × ... × n】

【利用前所学知识完善】:

def factorial(n):
    result = 1
    for i in range(1, n + 1):
        result *= i

    return result

【笔记】复习【字符串格式化%d】


递归方法

def factorial(n):
    if n == 1:
        return 1
    else:
        return n * factorial(n-1)
   
number = int(input('请输入一个正整数:'))
result = factorial(number)
print("%d 的阶乘是: %d" % (number, result))

【原理】 

 递归很牛逼,但 只要会选择运用场景,就是天才编程师!
        递归有风险,运用要谨慎!下节课讲 !~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值