一.函数递归

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

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

  函数的递归调用其实就是用函数实现的循环
# 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. C#从1970年开始到现在时间的总秒数

    TimeSpan timeSpan = (DateTime.UtcNow - new DateTime(1970, 1, 1)); string timeStamp = ((int)timeSpan. ...

  2. 死磕Spring之IoC篇 - 文章导读

    该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...

  3. 怎么去掉右下角的thinkphp的图标

    关闭thinkphp右下角的trace可以试试以下步骤: 1.在入口文件index.php 加入 define("APP_DEBUG", false); 2.在config.php ...

  4. JS常用数值验证

    1.正整数验证 正整数是大于0的整数. function validateInteger(val) { return Number.isInteger(val) && val > ...

  5. 使用EF的Code First模式创建模型

    Entity Framework Core Entity Framework (EF) Core 是轻量化.可扩展.开源和跨平台版的常用 Entity Framework 数据访问技术. EF Cor ...

  6. Ctfweb(2)

    CTFwebshow(2): phps源码泄露 思路:第一次接触phps这个后缀,第一眼打开的时候是想着用御剑去扫目录,但是很遗憾没有扫到index.phps,然后用burp抓包返回包信息也没有看到端 ...

  7. vs调试qt代码,无法单步调试

    在使用vs调试qt代码时,可以编译但无法单步调试QT源码.报错缺少qmain_win.cpp或者其他q******.cpp文件. 1.因为安装qt时没有安装qt源码库,重新下载一个src源码就可以了. ...

  8. 清除浏览器默认样式的reset.css(转载于reset.css的官方)

    /* http://meyerweb.com/eric/tools/css/reset/ v2.0-modified | 20110126 License: none (public domain) ...

  9. Linux增删改查移文件、文件夹

    关于Linux中文件基本处理命令 (1)添加文件.文件夹(图例):touch Demo命令创建文件(Demo)为文件名. 即mkdir Temp命令为创建文件夹(Temp)为文件夹名. 创建文件.文件 ...

  10. 白嫖微软Azure12个月服务器

    前言 Azure是微软提供的一个云服务平台.是全球除了AWS外最大的云服务提供商.Azure是微软除了windows之外另外一个王牌,微软错过了移动端,还好抓住了云服务.这里的Azure是Azure国 ...