一.函数递归

  函数的递归调用:是函数嵌套调用的一种特殊形式

  具体指的是在调用一个函数的过程中又直接或者间接地调用自己,称之为函数的递归调用

  函数的递归调用其实就是用函数实现的循环
# def f1():
# print('from f1')
# f1() # f1() 或者 # def f1():
# print('f1')
# f2()
#
# def f2():
# print('f2')
# f1()
#
# f1()
一个递归的过程应该分为两个阶段:
 1、回溯:向下一层一层调用
 2、递推:向上一层一层返回 
#1

# age(5) = age(4) + 10
# age(4) = age(3) + 10
# age(3) = age(2) + 10
# age(2) = age(1) + 10
#
# age(1) = 18
#
# n > 1 -> age(n) = age(n-1) + 10
# n = 1 -> age(1) = 18 # def age(n):
# if n == 1:
# return 18
# return age(n-1) + 10
#
# res = age(5)
# print(res) #2
# nums = [1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]
#
# def func(nums):
# for item in nums:
# if type(item) is list:
# func(item)
# else:
# print(item)
#
# func([1,[2,[3,[4,[5,[6,[7,[8,]]]]]]]]) #3
nums = [-3,1,5,7,9,11,13,18,22,38,78,98] # for num in nums:
# if num == find_num:
# print('find it')
# break def search(find_num,nums):
print(nums)
if len(nums) == 0:
print('not exists')
return
mid_index = len(nums) // 2
if find_num > nums[mid_index]:
# in the right
new_nums = nums[mid_index+1:]
search(find_num,new_nums)
elif find_num < nums[mid_index]:
# in the left
new_nums = nums[:mid_index]
search(find_num,new_nums)
else:
print('find it') # search(22,nums)
search(23,nums)

二.匿名函数

对比使用def关键字创建的是有名字的函数,使用lambda关键字创建则是没有名字的函数,即匿名函数,语法如下

# 1、定义
lambda x,y,z:x+y+z #等同于
def func(x,y,z):
return x+y+z # 2、调用
# 方式一:
res=(lambda x,y,z:x+y+z)(1,2,3) # 方式二:
func=lambda x,y,z:x+y+z # “匿名”的本质就是要没有名字,所以此处为匿名函数指定名字是没有意义的
res=func(1,2,3)

   匿名函数与有名函数有相同的作用域,但是匿名意味着引用计数为0,使用一次就释放,所以匿名函数用于临时使用一次的场景,匿名函数通常与其他函数配合使用

#取得薪水的最大值和最小值
salaries={
'siry':3000,
'tom':7000,
'lili':10000,
'jack':2000
} # 函数max会迭代字典salaries,每取出一个“人名”就会当做参数传给指定的匿名函数,然后将匿名函数的返回值当做比较依据,最终返回薪资最高的那个人的名字
>>> max(salaries,key=lambda k:salaries[k])
'lili'
# 原理同上
>>> min(salaries,key=lambda k:salaries[k])
'jack'

三.map、reduce、filter

  函数map、reduce、filter都支持迭代器协议,用来处理可迭代对象,我们以一个可迭代对象array为例来介绍它们三个的用法

array=[1,2,3,4,5]

1.map

要求一:对array的每个元素做平方处理,可以使用map函数
map函数可以接收两个参数,一个是函数,另外一个是可迭代对象,具体用法如下
>>> res=map(lambda x:x**2,array)
>>> res
<map object at 0x1033f45f8>
>>>
解析:map会依次迭代array,得到的值依次传给匿名函数(也可以是有名函数),而map函数得到的结果仍然是迭代器。
>>> list(res) #使用list可以依次迭代res,取得的值作为列表元素
[1, 4, 9, 16, 25]

2.reduce

要求二:对array进行合并操作,比如求和运算,这就用到了reduce函数
reduce函数可以接收三个参数,一个是函数,第二个是可迭代对象,第三个是初始值
# reduce在python2中是内置函数,在python3中则被集成到模块functools中,需要导入才能使用
>>> from functools import reduce
>>> res=reduce(lambda x,y:x+y,array)
>>> res
15
解析:1 没有初始值,reduce函数会先迭代一次array得到的值作为初始值,作为第一个值数传给x,然后继续迭代一次array得到的值作为第二个值传给y,运算的结果为3
2 将上一次reduce运算的结果作为第一个值传给x,然后迭代一次array得到的结果作为第二个值传给y,依次类推,知道迭代完array的所有元素,得到最终的结果15
也可以为reduce指定初始值
>>> res=reduce(lambda x,y:x+y,array,100)

>>> res
115

3.filter

要求三:对array进行过滤操作,这就用到了filter函数,比如过滤出大于3的元素
>>> res=filter(lambda x:x>3,array)
解析:filter函数会依次迭代array,得到的值依次传给匿名函数,如果匿名函数的返回值为真,则过滤出该元素,而filter函数得到的结果仍然是迭代器。
>>> list(res)
[4, 5]

 提示:我们介绍map、filter、reduce只是为了带大家了解函数式编程的大致思想,在实际开发中,我们完全可以用列表生成式或者生成器表达式来实现三者的功能。 

四.模块

1、什么是模块
    模块就是一系列功能的集合体
    模块分为四种类别:
        1、一个py文件就可以是一个模块
        2、包:就是一个存放有__init__.py文件的文件夹
 
        3、使用C编写并链接到python解释器的内置模块
        4、已被编译为共享库或DLL的C或C++扩展
 
    模块有三种来源
        1、python解释器自带的
            内置的
            标准库
            import time  # 内置库
            print(time)
            import os  # 标准库
            print(os)
 
        2、第三方的库
        3、自定义的库
2、为何要用模块
    1、拿来主义,极大地提升开发效率
    2、解决代码冗余问题
 
3、模块用法
1.import
import foo #导入模块foo
a=foo.x #引用模块foo中变量x的值赋值给当前名称空间中的名字a
foo.get() #调用模块foo的get函数
foo.change() #调用模块foo中的change函数
obj=foo.Foo() #使用模块foo的类Foo来实例化,进一步可以执行obj.func()
  #加上foo.作为前缀就相当于指名道姓地说明要引用foo名称空间中的名字,所以肯定不会与当前执行文件所在名称空间中的名字相冲突,并且若当前执行文件的名称空间中存在x,执行foo.get()或foo.change()操作的都是源文件中的全局变量x。  
  #需要强调一点是,第一次导入模块已经将其加载到内存空间了,之后的重复导入会直接引用内存中已存在的模块,不会重复执行文件,通过import sys,打印sys.modules的值可以看到内存中已经加载的模块名。# 后续的导入直接引用首次导入的成果
 
   #首次导入模块发生三件事
   1、会触发spam.py运行,所以会产生一个模块的名称空间
   2、运行spam.py的代码,将运行过程中产生的名字都丢到模块的名称空间中
   3、在当前执行文件的名称空间中拿到一个名字spam,该名字就是指向模块的名称空间的

2.from-import 语句

from...import...与import语句基本一致,唯一不同的是:使用import foo导入模块后,引用模块中的名字都需要加上foo.作为前缀,而使用from foo import x,get,change,Foo则可以在当前执行文件中直接引用模块foo中的名字,如下

from foo import x,get,change #将模块foo中的x和get导入到当前名称空间
a=x #直接使用模块foo中的x赋值给a
get() #直接执行foo中的get函数
change() #即便是当前有重名的x,修改的仍然是源文件中的x

3.其它

(1)  *

from foo import * #把foo中所有的名字都导入到当前执行文件的名称空间中,在当前位置直接可以使用这些名字

a=x
get()
change()
obj=Foo()

(2)as

#为导入的模块起别名
import foo as f #为导入的模块foo在当前位置起别名f,以后再使用时就用这个别名f
f.x
f.get() #为导入的名字起别名
from foo import get as get_x
get_x()

4.循环导入问题

详见: https://zhuanlan.zhihu.com/p/109127048 

5.搜索模块的路径与优先级

在导入一个模块时,如果该模块已加载到内存中,则直接引用,否则会优先查找内置模块,然后按照从左到右的顺序依次检索sys.path中定义的路径,直到找模块对应的文件为止,否则抛出异常。sys.path也被称为模块的搜索路径,它是一个列表类型

>>> sys.path
['',
'/Library/Frameworks/Python.framework/Versions/3.5/lib/python35.zip',
'/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5',
...,
'/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages'

6. 区分py文件的两种用途

一个Python文件有两种用途:

   (1)一种被当主程序/脚本执行

   (2)另一种被当模块导入

#为了区别同一个文件的不同用途,每个py文件都内置了__name__变量,该变量在py文件被当做脚本执行时赋值为“__main__”,在py文件被当做模块导入时赋值为模块名

day12.函数其它与模块1的更多相关文章

  1. sheet目标数据插入函数主键模块

    #coding:gbk #导入处理excel的模块 import xlrd #定义哪些字段需要判断,只支持时间字段 toSureColArray = ['CREATE_TIME','MODIFY_TI ...

  2. python协程函数、递归、匿名函数与内置函数使用、模块与包

    目录: 协程函数(yield生成器用法二) 面向过程编程 递归 匿名函数与内置函数的使用 模块 包 常用标准模块之re(正则表达式) 一.协程函数(yield生成器用法二) 1.生成器的语句形式 a. ...

  3. Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究

    Python进阶----反射(四个方法),函数vs方法(模块types 与 instance()方法校验 ),双下方法的研究 一丶反射 什么是反射: ​ 反射的概念是由Smith在1982年首次提出的 ...

  4. Python标准库-数字的处理函数(math模块)

    Python标准库-数字的处理函数(math模块) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. #!/usr/bin/env python #_*_conding:utf-8_* ...

  5. 函数的学习3——传递任意数量的实参&将函数存储在模块——参考Python编程从入门到实践

    传递任意数量的实参 形参前加一个 * ,Python会创建一个已形参为名的空元组,将所有收到的值都放到这个元组中: def make_pizza(*toppings): print("\nM ...

  6. python 函数3(模块)

    1.将函数存储在模块中 1.1.导入整个模块 要将函数导入,得先创建模块,模块 是扩展名为.py的文件,包含要导入到程序中的代码. 首先定义编写一个.py的文件,命名为pizza.py,代码如下: d ...

  7. Python --函数学习3 (将函数存储在模块中)

    将函数存储在模块 函数可以将代码块和主程序分离,通过给函数指定描述性名称,可以让主程序更加容易理解,还可以更进一步,将函数存储在模块的独立文件中,再将模块导入到主程序.import 语句允许再当前运行 ...

  8. day12 函数嵌套

    day12 函数嵌套 一. args与kwargs def index(a,b,c): print(a,b,c) def wrapper(*args,**kwargs): # args=(1,2,3) ...

  9. python函数和常用模块(三),Day5

    递归 反射 os模块 sys模块 hashlib加密模块 正则表达式 反射 python中的反射功能是由以下四个内置函数提供:hasattr.getattr.setattr.delattr,改四个函数 ...

随机推荐

  1. 一条sql语句的执行过程

    一条select语句执行流程 第一步:连接器 连接器负责跟客户端建立连接.获取权限.维持和管理连接.如果用户名密码验证通过后,连接器会到权限表里面查出你拥有的权限.之后该连接的权限验证都依赖于刚查出来 ...

  2. 鸿蒙Java开发模式11:鸿蒙图片裁剪功能的实现

    鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 目录: 1. 鸿蒙版图片裁剪功能效果展示 2.Java代码实现 3.裁剪工具类实现 4.<鸿蒙Java开发模式>系 ...

  3. vue路由理解

    vue路由:就是一个菜单的概念比如说有一个菜单栏,菜单栏上有很多按钮,当你点击一个按钮时会出现不同的页面,这就是vue路由

  4. Django简单的使用及一些基础方法

    目录 一.静态文件配置 1. 什么是静态文件 2. 静态文件的用法 3. 静态文件的动态绑定 二.请求方式与相应 1. get请求 2. post请求 3. Django后端视图函数处理请求 三.re ...

  5. gojs插件使用教程

    目录 一.简介 二.简单使用 三.重要概念 1.TextBlock创建文本 2.Shape图形 3.Node节点(文本与图形结合) 4.Link箭头 四.数据绑定(前后端交互数据渲染) 五.去除水印 ...

  6. 第48天学习打卡(CSS)

    HTML + CSS +JavaScript 结构+表现+交互 HTML:结构 CSS:表现 JavaScript:交互 1什么是CSS 如何学习 ​ 1.CSS是什么 ​ 2.CSS怎么用(快速入门 ...

  7. C++中tuple类型

    tuple是C++11新标准里的类型.它是一个类似pair类型的模板.pair类型是每个成员变量各自可以是任意类型,但是只能有俩个成员,而tuple与pair不同的是它可以有任意数量的成员.但是每个确 ...

  8. 剑指 Offer 58 - II. 左旋转字符串 + 简单题

    剑指 Offer 58 - II. 左旋转字符串 Offer_58_2 题目描述 java代码 package com.walegarrett.offer; /** * @Author WaleGar ...

  9. HashMap之tableSizeFor方法图解

    目录 普通人的简单粗暴方式 示例代码 问题 大神的实现 移位的思想 全过程示意图 初始值 右移一位+或运算 右移二位+或运算 右移四位+或运算 右移八位+或运算 右移十六位+或运算 结果+1 初始容量 ...

  10. 测试平台系列(4) 使用Flask蓝图(blueprint)

    使用Flask蓝图(blueprint) 回顾 先来看一下上一篇的作业吧,使用「logbook」的时候,遇到了时区不对的情况.那么我们怎么去解决这个问题呢? 实际上logbook默认采用的是世界标准时 ...