Python day16:函数递归,三元表达式,匿名函数,模块

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

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

foo()  # 死递归,会抛出异常,调用python对象超过最大递归深度

示例2:间接调用自己

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

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

foo()  # 也会抛出异常

为何死递归会抛出异常???
应为无限的递归会导致内存溢出,所以python设定了最大的递归层数,我们应该给递归设置结束条件,然后返回

import sys
print(sys.getrecursionlimit())  # 可查看当前最大递归层数
print(sys.setrecursionlimit(2000))  # 可设置新的最高递归层数

2.递归调用
应该分为两个阶段
①、回溯(挖井) :一层一层地递归调用下去
②、递推(从井里往外跳):在满足某一条件的情况下结束回溯,然后开始向上一层层返回
小案例:计算年龄,小一说比小二多大十岁,小二比小三大十岁,小三比小四大十岁,小四比小五大十岁。

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)

二分法使用场景:

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)


'''
从小到大排列的一个数字列表,找某个数是否在其中
'''
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)

3.递归的应用场景:当你不知道该重复做多少次,但是知道在什么情况下该结束的时候,用递归会很好。

二、三元表达式

'''
对于这样一个判断条件,就产生结果的函数,可以用三元表达式简化,省去了构造函数
'''
def max2(x,y):
    if x > y:
        return x
    else:
        return y

三元表达式: res = 表达式1 if 条件 else 表达式2
x=111
y=222

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

三、匿名函数:
匿名函数即没有名字的函数

res=(lambda x,y:x+y)(1,2)
print(res)

f = lambda x, y: x + y
print(f)
f(1, 2)

特点:没有名字意味着只能用一次,用完之后就被当成垃圾回收,所以匿名函数只用于临时使用一次的场景

'''
匿名函数常常与一些函数搭配使用
'''
salaries = {
    'egon': 4.4,
    "lqz": 3.3,
    'yj': 2.2
}


def func(k):
    return salaries[k]

print(max(salaries, key=lambda k:salaries[k]))
print(min(salaries, key=lambda k:salaries[k]))
print(sorted(salaries,key=lambda k:salaries[k],reverse=True))

四、模块
1、什么是模块
模块就是一个功能的集合体,不是用来直接运行,而是用来被导入使用的

模块分为三大来源:
    1、内置的模块
    2、第三方模块
    3、自定义的模块

模块分为四种类别:
    **1、一个py文件就是一个模块**
    **2、一个文件夹也是一个模块=》包**
    3、已被编译为共享库或DLL的C或C++扩展
    4 使用C编写并链接到python解释器的内置模块

2、为何要用模块
使用别人的模块:
1、拿来主义,提升开发效率
自定义模块:
1、他人的功能无法满足所有,有些功能需要自己编写
2、解决代码冗余

3、如何用模块
当前我们有一个spam.py的文件,内容如下:

# spam.py
print('from the spam.py')
__all__ = ['money', 'read1']  # 利用__all__可以限制*号的导入,表示只对*开发其后的功能,若不写,默认全开放

money = 1000

def read1():
    print('spam模块:', money)

def read2():
    print('spam模块')
    read1()

def change():
    global money
    money = 0

文件名是spam.py,模块名则是spam

'''
导入方法1:
import spam  # 导入模块,会运行py文件的代码
方法1导入模块发生的事情
1、触发被导入的模块的运行,产生一个模块的名称空间,把模块中的名字都丢进去
2、会在当前执行文件中得到一个名字spam,该名字是指向被导入模块的名称空间的
方法1使用模块的方法:
'''
import spam

print(money)
print(spam.money)

spam.read1()
spam.read2()
spam.change()

print(spam.money)
print(money)
----------------------------------
from the spam.py
10
1000
spam模块: 1000
spam模块
spam模块: 1000
0
10
'''
导入方法2:
from spam import *  #导入模块,运行py文件代码
方法2导入模块发生的事情
1、触发被导入的模块的运行,产生一个模块的名称空间,把模块中的名字都丢进去
2、会在当前执行文件中得到名字
   money=模块spam中的money对应值的内存地址
   read1=模块spam中的read1对应值的内存地址
   read2=模块spam中的read2对应值的内存地址
------------------------------------
from the spam.py
'''
from spam import *

print(money)
money=111
print(money)  # 利用from import导入,有时会名称覆盖
--------------------------------------------------------
from the spam.py
1000
111

money=2000
read1()
----------------------------
from the spam.py
spam模块: 1000

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

一行导入多个模块
import spam,m1,m2,m3  # 不推荐

为导入的模块起别名
import spamasdfasfsadfadfasfd as spam
起别名的好处,小案例
示例:
#mysql.py
def sqlparse():
    print('from mysql sqlparse')
#oracle.py
def sqlparse():
    print('from oracle sqlparse')

#test.py
db_type=input('>>: ')
if db_type == 'mysql':
    import mysql as db
elif db_type == 'oracle':
    import oracle as db  # 取一样的别名,就使得我们后续的代码不用修改

db.sqlparse()
...很多代码使用db.xxx的代码

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