美文网首页
day16-递归调用与模块

day16-递归调用与模块

作者: 天行_b6d0 | 来源:发表于2020-07-23 20:41 被阅读0次

函数的递归调用

一:引入

函数的递归调用:就是在调用一个函数的过程中又直接或间接地调用自己

示例1:直接调用自己
def foo():
    print('hello')
    foo()

foo()
示例2:间接调用自己
def bar():
    print('from bar')
    foo()

def foo():
    print('hello')
    bar()

foo()

为何"死递归"会抛出异常???
因为无限的递归会导致内存溢出,所以python设定了最大的递归层数,这个最大递归层数可以自己设置,但是一般情况下python自身设定的层就已经足够使用了。

import sys
print(sys.getrecursionlimit())
print(sys.setrecursionlimit(2000))

所以:不应该无限递归调用下去,应该在满足某种条件下结束递归调用,然后返回

二:递归调用应该分为两个阶段

1、回溯(挖井) :一层一层地递归调用下去
2、递推(从井里往外跳):在满足某一条件的情况下结束回溯,然后开始向上一层层返回

例1:
salary(5) = salary(4) + 10
salary(4) = salary(3) + 10
salary(3) = salary(2) + 10
salary(2) = salary(1) + 10
salary(1) = 18


n=1   salary(n) = 18
n!=1  salary(n) = salary(n-1) + 10

def salary(n):
    if n == 1:
        return 18
    return salary(n-1) + 10

res=salary(5)
print(res)
例2:将列表中的数字打印出来
nums=[111,[222,[333,[444,[5555,[6666,[777,[888,[9999]]]]]]]]]


def func(l):
    for x in l:
        if type(x) is list:
            # 把自身的代码重新再调用一次
            func(x)
        else:
            print(x)
func(nums)
例3:从小到大排列的一个数字列表,查找某个数是否在里面
nums = [11, 13, 32, 47, 53, 73, 84, 91,101,111,222,333,444,5555]


def binary_search(l,find_num):
    print(l)
    if len(l) == 0:
        print('find_num not exists')
        return
    mid_index = len(l) // 2
    if find_num > l[mid_index]:
        right_l=l[mid_index+1:]
        binary_search(right_l,find_num)
    elif find_num < l[mid_index]:
        left_l=l[:mid_index]
        binary_search(left_l,find_num)
    else:
        print('find it')


binary_search(nums,85)

三元表达式

如下为判断两个数大小的一段:

def max2(x,y):
    if x > y:
        return x
    else:
        return y

可以使用三元表达式简化:

x=111
y=222
res=x if x > y else y
print(res)

三元表达式: 表达式1 if 条件 else 表达式2

列表生成式

1、示例

egg_list=[]
for i in range(10):
    egg_list.append('鸡蛋%s' %i)

egg_list=['鸡蛋%s' %i for i in range(10)]

2、语法

[expression for item1 in iterable1 if condition1
for item2 in iterable2 if condition2
...
for itemN in iterableN if conditionN
]
类似于
res=[]
for item1 in iterable1:
    if condition1:
        for item2 in iterable2:
            if condition2
                ...
                for itemN in iterableN:
                    if conditionN:
                        res.append(expression)

3、优点:方便,改变了编程习惯,可称之为声明式编程

匿名函数

一、什么是匿名函数
匿名就是没有名字
def func(x,y,z=1):
    return x+y+z

匿名
lambda x,y,z=1:x+y+z #与函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,除非让其有名字
func=lambda x,y,z=1:x+y+z 
func(1,2,3)
#让其有名字就没有意义
二、有名函数和匿名函数对比

有名函数:循环使用,保存了名字,通过名字就可以重复引用函数功能

匿名函数:一次性使用,随时随时定义

匿名函数的应用:max,min,sorted,map,reduce,filter

模块

1、什么是模块

模块就是一组功能的集合体,我们的程序可以导入模块来复用模块里的功能。

模块可以分为四个通用类别:

--  1 使用python编写的.py文件

--  2 已被编译为共享库或DLL的C或C++扩展

--  3 把一系列模块组织到一起的文件夹(注:文件夹下有一个init.py文件,该文件夹称之为包)

--  4 使用C编写并链接到python解释器的内置模块

2、为什么要使用模块

1、从文件级别组织程序,更方便管理
随着程序的发展,功能越来越多,为了方便管理,我们通常将程序分成一个个的文件,这样做程序的结构更清晰,方便管理。这时我们不仅仅可以把这些文件当做脚本去执行,还可以把他们当做模块来导入到其他的模块中,实现了功能的重复利用

2、拿来主义,提升开发效率
同样的原理,我们也可以下载别人写好的模块然后导入到自己的项目中使用,这种拿来主义,可以极大地提升我们的开发效率

ps:
如果你退出python解释器然后重新进入,那么你之前定义的函数或者变量都将丢失,因此我们通常将程序写到文件中以便永久保存下来,需要时就通过python test.py方式去执行,此时test.py被称为脚本script。

3、如何使用模块(以spam为例)

(1)import

import spam
首次导入模块发生的事情
1、触发被导入的模块的运行,产生一个模块的名称空间,把模块中的名字都丢进去。

2、会在当前执行文件中得到一个名字spam,该名字是指向被导入模块的名称空间的。

3、之后的导入,名字spam直接引用首次导入产生的名称空间,不会再执行模块的内的代码了

可以在一行导入多个模块
import spam,m1,m2,m3  # 不推荐
如果导入的模块名过长可以修改它的名称
import spamasdfasfsadfadfasfd as sm
sm.xxx
(2)from...import...as...
  • 1、和import唯一的区别就是:使用from...import...则是将spam中的名字直接导入到当前的名称空间中,所以在当前名称空间中,直接使用名字就可以了、无需加前缀:spam.

  • 2、from...import...的方式有好处也有坏处
    -- 好处:使用起来方便了
    -- 坏处:容易与当前执行文件中的名字冲突

  • 3、from spam import * 把spam中所有的不是以下划线(_)开头的名字都导入到当前位置

ps:大部分情况下我们的python程序不应该使用这种导入方式,因为*你不知道你导入什么名字,很有可能会覆盖掉你之前已经定义的名字。而且可读性极其的差,在交互式环境中导入时没有问题

  • 4、可以使用_all_来控制*(用来发布新版本),在spam.py中新增一行

_all_=['money','read1'] # 这样在另外一个文件中用from spam import *就这能导入列表中规定的两个名字

相关文章

  • day16-递归调用与模块

    函数的递归调用 一:引入 函数的递归调用:就是在调用一个函数的过程中又直接或间接地调用自己 示例1:直接调用自己 ...

  • Python 递归调用与二分法

    递归调用与二分法 1、递归调用 递归调用:在调用一个函数的过程中,直接或间接地调用了函数本身. 递归的执行分为两个...

  • Python语言程序---代码复用与函数递归(二)

    Python语言程序---代码复用与函数递归(二) 函数递归 在函数定义中,调用函数自身的方式就是递归。 递归并不...

  • 递归调用

    什么是递归调用 递归调用就是在本函数中连续不断地对自身函数进行调用。 递归调用注意点 递归调用函数要有明确的某一或...

  • 从示例逐渐理解Scala尾递归

    1.递归与尾递归 1.1 递归 1.1.1 递归定义 递归大家都不陌生,一个函数直接或间接的调用它自己本身,就是递...

  • [每天进步一点点~] 递归与闭包

    1.递归 【定义】:在自己函数的内部调用自己(自己调用自己) (函数自调用) 。递归函数 简单举例?: 阶乘的递归...

  • Python开启尾递归优化!

    原文出处: neo1218 一般递归与尾递归 一般递归 执行: 可以看到, 一般递归, 每一级递归都需要调用函数,...

  • 重复

    递归在自己的定义中调用自己的函数叫做递归函数(Recursive Function)。 尾递归普通的递归调用并不高...

  • 函数递归调用

    在函数里调用自己的行为:函数递归调用 递归调用一定要有最后一次递归时的终止条件,如果没有,会导致无限调用,导致调用...

  • 单信js——4难点部分

    递归: 递归函数是指在函数内部调用函数自身。注意:递归的出口:什么情况下结束调用递归的入口:什么情况下调用自已 /...

网友评论

      本文标题:day16-递归调用与模块

      本文链接:https://www.haomeiwen.com/subject/ockhlktx.html