澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站学习笔记,高阶函数

2019-12-12 作者:www.8455.com   |   浏览(80)

生机勃勃、函数效能:

生龙活虎. 背景提要

到现在首席营业官令你写三个监督检查程序,监察和控制服务器的连串意况,当cpu\memory\disk等目的的使用量超过阀值时即发邮件报告急察方,你掏空了有着的知识量,写出了以下代码

while True:
    if cpu利用率 > 90%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接

    if 硬盘使用空间 > 90%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接

    if 内存占用 > 80%:
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接

上面包车型客车代码达成了意义,但即使是邻里老王也看到了眉目,老王亲近的摸了下你家孙子的脸蛋儿,说,你这一个重复代码太多了,每便报告急察方都要重写风华正茂段发邮件的代码,太low了,那样干存在2个难题:

  1. 代码重复过多,四个劲的copy and paste不合乎高等技术员的风姿
  2. 万一之后供给更改发邮件的这段代码,举例到场群发功效,那您就须求在全数用到这段代码的地点都改正二遍

你认为老王说的对,你也不想写重复代码,但又不亮堂怎么搞,老王好像看出了您的念头,这时候他抱起你孙子,笑着说,其实比极粗略,只供给把重复的代码提收取来,放在叁个共用之处,起个名字,今后什么人想用这段代码,就由此这几个名字调用就能够了,如下:

def 发送邮件(内容)
    #发送邮件提醒
    连接邮箱服务器
    发送邮件
    关闭连接

while True:

    if cpu利用率 > 90%:
        发送邮件('CPU报警')

    if 硬盘使用空间 > 90%:
        发送邮件('硬盘报警')

    if 内存占用 > 80%:
        发送邮件('内存报警')

你望着老王写的代码,宏伟壮观、磅礴大气,代码里揭露着一股内敛的骄贵,心想,老王这厮真是不平时,蓦然对她的背景更感兴趣了,问老王,这么些花式耍法你都以怎么明白的? 老王亲了一口你孙子,捋了捋不设有的胡须,淡淡的讲,“老夫,年少时,师从京西沙河淫魔银角大王 ”, 你风流倜傥听“银角大王”那多少个字,不由的娇躯意气风发震,心想,真nb,怪不得代码写的如此6, 那“银角大王”当年在下方上不过数得着的资深的名字,只可惜后期纵欲过度,卒于公元2015年, 真是缺憾了,只留下其兄长孤守当年兄弟俩一齐打下来的国度。 此时您看着的老王离开的人影,感到你外孙子跟他特别像了。。。

小结运用函数的平价:

1.代码录取

2.维持风华正茂致性,易维护

3.可扩展性

1. 函数

  函数是团协会好的,可重复使用的,用来落到实处单意气风发,或有关职能的代码块。

  函数分为 Python 程序嵌入函数,客商自定义的函数。将代码定义为函数,有如下好处:

  • 代码重用
  • 维持代码风度翩翩致性,易维护
  • 可拓展

上生龙活虎篇已经介绍到了高阶函数map,本节继续上课别的的多少个高阶函数

澳门新萄京官方网站学习笔记,高阶函数。本文笔记由Python入门和Python进阶两门学科收拾而来

  函数式:将某功效代码封装到函数中,日后便没有必要重新编写,仅调用函数就可以

二. 什么是函数?

函数后生可畏词来源于数学,但编程中的「函数」概念,与数学中的函数是有超级大区别的。

初级中学数学函数定义:日常的,在二个变通历程中,如若有四个变量x和y,並且对于x的每四个规定的值,y都有唯豆蔻梢头鲜明的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数。自变量x的取值范围叫做这个函数的定义域

例如  y=2*x

1.1 定义和调用函数

澳门新萄京官方网站学习笔记,高阶函数。  使用 def 关键字定义叁个函数,前边紧跟函数名,小括号也至关重要,语法如下:

def func():    函数体

  函数在推行时,首先将函数体加载到解释器中,可是不会运作,独有当调用函数后才会施行,函数名 小括号就能够调用函数:

def func():    函数体func()      # 调用函数  

map()函数

参数:选取三个函数 f 和叁个 list列表,并由此把函数 f 依次功用在 list 的种种成分上

再次来到值:获得新的 list 重临 (map函数不改造原本的列表,而回到新的列表卡塔尔国

示例:

>>> ks1 = [1,2,3,4,5,6,7,8,9]
>>> ku = map(lambda x: x 1, ks1)
>>> type(ku)
map
>>> list(ku)
[2, 3, 4, 5, 6, 7, 8, 9, 10]

列表 List

  1. list1 = ['physics', 'chemistry', 1997, 2000];
  2. 倒序访谈 [-1]下标访谈倒数第一个成分 [0]下标访问正数第二个因素
  3. 切片一直以来适用于元组

    >>> L[0:3]
    #L[0:3]表示,从索引0开始取,直到索引3为止,但不包括索引3。即索引0,1,2,正好是3个元素。
    ['physics', 'chemistry', 1997]
    #如果第一个索引是0,还可以省略:>>> L[:3]
    #也可以从索引1开始,取出2个元素出来:>>> L[1:3]
    #只用一个 '': ''表示从头取到尾:>>> L[:]
    #切片操作还可以指定第三个参数,表示每N个取一个:>>> L[::2]
    
  4. 倒序切成片

    >>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
    >>> L[-2:] //[-2~末尾]
    ['Bart', 'Paul']
    >>> L[:-2]//[0~-2)
    ['Adam', 'Lisa']
    >>> L[-3:-1]//[-3~-1)
    ['Lisa', 'Bart']
    >>> L[-4:-1:2]
    ['Adam', 'Bart']
    
  5. 列表生成式

    >>> range(1, 11)
    [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]#生成一个包含1-10的列表
    >>> [x * x for x in range(1, 11)]
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]#生成[1x1, 2x2, 3x3, ..., 10x10]
    #range(1, 100, 2) 可以生成list [1, 3, 5, 7, 9,...]
    
  6. 列表生成式 if决断

    >>> [x * x for x in range(1, 11) if x % 2 == 0]
    [4, 16, 36, 64, 100]
    
  7. 多层表达式

    >>> [m   n for m in 'ABC' for n in '123']
    ['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
    

  函数式编制程序最关键的是进步代码的重用性和可读性

2.1 python函数

函数是集团好的,可重复使用的,用来落到实处单意气风发,或相关联功能的代码段。

函数能增加运用的模块性,和代码的重复利用率。你已经掌握Python提供了重重内建函数,例如print(卡塔尔国。但您也得以团结创办函数,那被称呼顾客自定义函数。

python中函数定义:函数是逻辑构造化和进程化的风姿罗曼蒂克种编制程序方法。   可以理解为: 函数是指将后生可畏组语句的集中通过一个名字(函数名卡塔尔封装起来,要想实行这一个函数,只需调用其函数名就能够;

特性:

  1. 减去重复代码
  2. 使程序变的可扩充
  3. 使程序变得易维护

1.2 返回值

  有时我们要求函数再次来到一些数目来报告实施的结果,全数就供给有再次回到值,只要求在函数中加多return 关键字,后边随着再次来到值就能够。

def func():    return 1

  return 将再次来到值传递给函数自身,我们如若调用函数,再将函数赋值给变量就能够拿到重临值:

def func():    return 1res = func()        # 获得返回值,并赋值给变量 resprint1

  重临值能够是 0 个,也能够是 1 个 或七个:

  • 从没重临值,重返 None
  • 多少个重回值,重返 再次来到值
  • 八个重返值,重临八个元组
def func():    # return    # return 1    return 1, 2res = func()printNone1

reduce()函数

瞩目:Python3中,reduce不再是松开了,须求导入from functools import reduce

参数:一个函数 f,二个list

再次回到值:reduce(卡塔尔(قطر‎传入的函数 f 必需选择多个参数,reduce(卡塔尔对list的每种成分屡屡调用函数f,并再次回到最后结果值。

>>> ks2 = [2,4,6,8]
>>> ku2 = reduce(lambda x,y: x y, ks2)
>>> type(ku2)
int
>>> ku2
20

元组 Tuple

  1. t = ('Adam', 1, 'Bart')
  2. 元组定义后无法改正,tuple未有append(卡塔尔(英语:State of Qatar)方法,也远非insert(卡塔尔(英语:State of Qatar)和pop(卡塔尔(قطر‎方法。
  3. 空tuple >>> t = ()
  4. 创办单成分数值tuple >>> t = (1,)
  5. 目录迭代

    for index, name in enumerate(L):
    print index, '-', name
    #由 enumerate() 函数自动把每个元素变成 (index, element) 这样的tuple,再迭代,就同时获得了索引和元素本身
    

二、函数的概念和应用

2.2 定义贰个函数

您能够定义三个由友好想要作用的函数,以下是简简单单的规行矩步:

  • 函数代码块以 def 关键词初叶,后接函数标记符名称和圆括号()
  • 其余传入参数和自变量必需放在圆括号中间。圆括号之间能够用于定义参数。
  • 函数的第风流洒脱行语句能够选用性地运用文书档案字符串—用于寄存函数表达。
  • 函数内容以冒号起首,何况缩进。
  • return [表达式] 甘休函数,选取性地赶回四个值给调用方。不带表明式的return也等于返回None。

语法定义:

def sayhi():                 # def:定义函数的关键字,函数名:sayhi,()内可以指定形参
  """The function definitions"""     # 文档描述(非必要,但是强烈建议为你的函数添加描述信息)
    print("Hello, I'm nobody!")       # 泛指代码块或程序处理逻辑
sayhi()                   # 调用函数,通过函数名()的形式

1.3 函数参数

  函数的参数能够用函数完结本性化,大概分成两类:

  • 形参:函数在概念时定义的参数
  • 实参:函数在调用时传出的参数

  形参独有在调用时才分配内部存款和储蓄器单元,调用甘休,就自由。仅在函数内部有效,不能够在函数外界使用。

  实参能够是常量、变量、表明式、函数,占用内部存储器空间。

filter()函数

filter(卡塔尔(英语:State of Qatar)函数是 Python 内置的很有用的高阶函数,简单称谓高阶过滤函数。

参数:filter(卡塔尔(قطر‎函数接纳一个函数 f 和二个list,那么些函数 f 的效能是对种种成分举办剖断,重回 True或 False。filter(卡塔尔依照推断结果自动过滤掉不适合条件的成分。

重回值:重临由切合条件成分结合的新list。

>>> ks3 = [22,3,12,3,1,44,0,2,4,6,28,55,34]
>>> ku3 = filter(lambda x: x>5, ks3)
>>> type(ku3)
filter
>>> list(ku3)
[22, 12, 44, 6, 28, 55, 34]

用事实说话,Python3内置高阶函数

完整的Python3教程--传送门

字符串 string

  定义:

2.3 函数和经过

进程定义:进程即使简单特殊未有重返值的函数

那般看来大家在座谈为什么采取函数的的时候引进的函数,都不曾再次来到值,未有再次回到值正是经过,没有错,但是在python中有相比较奇妙的事体:

def test01():
    msg = 'hello The little green frog'
    print
    msg

def test02():
    msg = 'hello WuDaLang'
    print
    msg
    return msg

t1 = test01()
t2 = test02()

print('from test01 return is [%s]' % t1)
print('from test02 return is [%s]' % t2)

总结: 当三个函数/进度未有使用return突显的定义再次回到值时,python解释器会隐式的回来None,

就此在python中尽管是进程也足以算作函数。

def test01():
    pass

def test02():
    return 0

def test03():
    return 0, 10, 'hello', ['alex', 'lb'], {'WuDaLang': 'lb'}

t1 = test01()
t2 = test02()
t3 = test03()

print('from test01 return is [%s]: ' % type(t1), t1)
print('from test02 return is [%s]: ' % type(t2), t2)
print('from test03 return is [%s]: ' % type(t3), t3)

总结:

   再次回到值数=0:重回None

   再次来到值数=1:重返object

   重临值数>1:重返tuple

1.3.1 暗中同意参数

  形参又分为:私下认可参数、地点参数、关键字参数以至可变长参数,而默许参数即在函数定义时暗中认可付与有些形参二个值。若函数调用时,不传播实参,函数使用暗中认可值,不然使用实参。

def func:      # x 默认为 2    return x   2res = func()        # 即使不传入实参函数也能正常运行print

字典 dict

  1. 定义

    d = {
    'Adam': 95,
    'Lisa': 85,
    'Bart': 59,
    'Paul': 75
    }
    
  2. 打字与印刷出的字典并不按给出顺序排列 原因是 字典对于成分的存放是因而hash算法 由此 dict是冬辰的

  3. 询问字典d['Adam']dict[key]
  4. 使用 in 操作符查询key是不是留存

    if 'Paul' in d:
    print d['Paul']
    
  5. 接收dict本人提供的八个 get 方法,在Key一纸空文的时候,重返None:

    >>> print d.get('Bart')
    59
    >>> print d.get('Paul')
    None
    
  6. key的因素类型能够是字符串 整数 浮点数 元组 , 而 value 的花色不限

  7. dict的特点:追寻速度快,但所用空间大,就义空间换取速度
  8. 除去字典dict.clear();
  9. 清空字典dict.clear();
  10. 迭代字典的Key

    d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59, 'Paul': 74 }
    sum = 0.0
    for v in d.itervalues():
    sum = sum   v
    print sum / len(d)
    
  11. 迭代字典的key和value

    >>> d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
    >>> print d.items()
    [('Lisa', 85), ('Adam', 95), ('Bart', 59)]
    >>> for key, value in d.items():
    ...     print key, ':', value
    ... 
    Lisa : 85
    Adam : 95
    Bart : 59
    
1 def 函数名(参数):
2     函数体
3     .....
4     返回值

2.4 函数实例:

实例1:

以下为二个大致的Python函数,它将三个字符串作为传播参数,再打字与印刷到正规展现设备上。

def printme( str ):
   "打印传入的字符串到标准显示设备上"
   print str
   return

# 调用函数
printme("我要调用用户自定义函数!");

实例2:

传送参数且有重回值的函数

a,b = 5,8
c = a**b
print(c)

#改成用函数写
def calc(x,y):
    res = x**y
    return res #返回函数执行结果

c = calc(a,b) #结果赋值给c变量
print(c)

注: 函数定义阶段只检查测量试验函数体的语法,并不会推行

1.3.2 地方参数和重大字参数

  普通的参数即为地点参数,在调用时实参必得与形参风华正茂生龙活虎对应。而重要字参数,能够毫无思量地点的涉嫌,只要求名字如出生龙活虎辙就能够。

def func(name, words):    print(name: words)func('Hello', words='world')    # 第一个为位置参数,第二个为关键字参数func(words='World', name='Hello')   # 不用考虑位置

Tips:岗位参数必得在第一字参数前边

集合 set

  1. set的元素还未重新,而且聚拢是冬日
  2. 创建 set s = set(['A', 'B', 'C'])//调用 set() 并传入一个 list
  3. 使用 in 操作符查询成分是还是不是留存

    >>> 'Bart' in s
    True
    
  4. 选择add(x卡塔尔添新币素

    >>> s = set([1, 2, 3])
    >>> s.add(4)
    >>> print s
    set([1, 2, 3, 4])
    
  5. 行使remove删除成分

    >>> s = set([1, 2, 3])
    >>> s.add(3)
    >>> print s
    set([1, 2, 3])
    

  -注- 

2.5 函数的调用

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

def bar(name):
    print('bar===>',name)

foo()  #调用函数foo
bar()  #调用函数bar

遵照有参和无参能够将函数调用分三种

foo()      # 定义时无参,调用时也无需传入参数
bar('egon') # 定义时有参,调用时也必须有参数

鲁人持竿函数的调用情势和现身的职位,分二种

foo() #调用函数的语句形式

def my_max(x,y):
    res=x if x >y else y
    return res
res=my_max(1,2)*10000000 #调用函数的表达式形式
print(res)

res=my_max(my_max(10,20),30) #把函数调用当中另外一个函数的参数
print(res)

1.3.3 可变长参数

  可变长参数是黄金时代种参数组,它能够是多少个参数,只必要在参数前增加星号就能够。它能够追加函数可拓宽性,当您不晓得定义的函数须要定义多少个参数时,使用它很有益。

  可变长参数分为:*args 和 **kwargs两类:

  • *agrs:将参数们征集起来,打包成贰个元组,再风流洒脱一传递给函数使用
  • **kwargs:将参数们征集并打包成一个字典

*args

  *args 、**kwargs 是 Python 官方概念的参数名,也能够是任何名字,不过最棒使用它,以便于辨认。

def func:    print    print('有 %d 个参数' % len    print('第三个参数是:', args[2])func('P', 'y', 't', 'h', 'o', 'n')func('Python', 123, '爬虫')

('P', 'y', 't', 'h', 'o', 'n')有 6 个参数第三个参数是: t('Python', 123, '爬虫')有 3 个参数第三个参数是: 爬虫

Tips:假设可变长参数前边还应该有参数,要将其定义为着重字参数,不然会被搜罗成可变长参数里面。建议在行使可变长参数时,可将其他参数设置为默许参数,或首要字参数,那样没有错混淆。

def func(*args, extra=16):# def func(*args, extra):    print    printfunc#func(5,6, extra=18)1618

  星号既可用来搜聚打包参数,也足以用来“解包”参数。当传入的参数时列表、元组、字典以致汇集时,可变长参数将会将其任何打包成独有三个元组的参数,而在其前方增添二个星号,就足以将里面包车型地铁因素一个个都解出来。

def func:    printl = [1, 2, 3]t = d = {'name':'rose', 'age': 18}funcfuncfuncfuncfuncfunc

([1, 2, 3],),)({'name': 'rose', 'age': 18},)('name', 'age')

**kwargs

  另意气风发种可变长参数正是 **kwargs,它将盛传的实参打包成一个字典,相似地也援助 “解包”。

def func(x, **kwargs):    print    print    print('总共有 %d 个参数' % len    print('这些参数分别为:', kwargs)func(20, name='rose', age=18)

20{'name': 'rose', 'age': 18}总共有 2 个参数这些参数分别为: {'name': 'rose', 'age': 18}

  解包,当传入的参数是字典时:

def func(gender, **kwargs):    print    print    print('总共有 %d 个参数' % len    print('这些参数分别为:', kwargs)t = {'name': 'rose', 'age': 18}func('female', **t)

female{'name': 'rose', 'age': 18}总共有 2 个参数这些参数分别为: {'name': 'rose', 'age': 18}

  当既有 *args,又有 **kwargs,以致岗位参数和职分参数时:

def func(gender, country='China', *args, **kwargs):    print(gender, country)    print    printfunc('male', 'America', 20, 30, name='rose', age=19)

male America{'name': 'rose', 'age': 19}

if语句

  1. Python使用4个空格作为缩进,相像缩进代码作为一个代码块
  2. if 语句后接表达式,然后用:表示代码块领头

    def:定义函数的要害字

2.6 函数的重临值

要想获得函数的推行结果,就足以用return语句把结果重临

注意:

  1. 函数在实践进度中如若碰着return语句,就能够停下实行并回到结果,so 也足以明白为 return 语句代表着函数的完工
  2. 设若未在函数中钦命return,那那一个函数的重返值为None
  3. return 一个值 函数调用重返的结果正是其风流倜傥值
  4. return 值1,值2,值3,... 再次回到结果:(值1,值2,值3,...卡塔尔(قطر‎

1.4 函数文书档案

  函数文书档案即用来说述函数成效的文书档案,能够令人家越来越好地掌握你的函数,定义函数文书档案是个好的习贯。

def func:    """    计算一个数加一    :param x:     :return:     """    x  = 1    return xres = func()

for循环

  1. 选择for语句遍历元组or列表

    L = ['Adam', 'Lisa', 'Bart']
    for name in L:
    print name
    

    重返值后方可跟几个值,最后以元组情势出口

2.7 自定义函数

概念函数的三种情势

  • 无参数函数:倘若函数的功效仅仅只是实施一些操作而已,就定义成无参函数,无参函数平时都有重返值
  • 概念有参函数:函数的效劳的举办重视于表面传入的参数,有参函数日常都有重返值
  • 空函数

 

1.5 函数变量

函数

  1. 定义

    def my_abs(x):
    if x >= 0:
        return x
    else:
        return -x
    
  2. 重返三个参数的函数(重回值是一个tuple卡塔尔国

    import math
    def move(x, y, step, angle):
    nx = x   step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny
    >>> x, y = move(100, 100, 60, math.pi / 6)
    >>> print x, y
    151.961524227 70.0
    
  3. 暗中同意参数 暗许参数只好定义在供给参数的后边

    def power(x, n=2):
    s = 1
    while n > 0:
        n = n - 1
        s = s * x
    return s
    
  4. 可变参数 名字前面有个 * 号,我们得以传入0个、1个或多个参数给可变参数:

    def average(*args):
    sum = 0.0
    if len(args) == 0:
        return sum
    for x in args:
        sum = sum   x
    return sum / len(args)
    print average()
    print average(1, 2)
    print average(1, 2, 2, 3, 4)
    

    函数的参数:形参、实参

三. 函数参数

形参: 变量独有在被调用时才分配内部存款和储蓄器单元,在调用停止时,马上释放所分配的内存单元。由此,形参只在函数内部有效。函数调用截至再次来到主调用函数后则不可能再利用该形参变量。

实参: 能够是常量、变量、表明式、函数等,无论实参是何系列型的量,在扩充函数调用时,它们都一定要有明确的值,以便把那么些值传送给形参。因而应事情未发生前用赋值,输入等措施使参数获得鲜明值。

澳门新萄京官方网站 1

1.5.1 函数和经过

  在 Python 中等高校函授数和经过是分手的,函数与经过(procedure)的区分:

  • 函数:有重回值
  • 过程:简单来说、特殊且无再次来到值

  严俊来讲 Python 未有经过,独有函数,因为尽管未有重回值,也会暗许再次来到叁个 None。

def func():    print('Hi')res = func()printHiNone

函数式编制程序

python协理的函数式编制程序
(1)它扶助的不是纯的函数式编制程序,因为它同意有变量;
(2)辅助高阶函数,即函数也得以视作变量传入;
(3)援救闭包,有了闭包就会回去三个函数;
(4)有限度地支撑无名氏函数。

高阶函数
1.变量能够本着函数,直接对变量调用与直接对函数调用效果是同等的。比如:f=abs
,正是把变量f指向绝对值函数abs。f(-20卡塔尔(英语:State of Qatar)就等于abs(-20)
2.函数名其实正是叁个指向性函数的变量的名字。比如:abs=len,那时abs那个名字就不指向绝对值函数,运算完了不畏取list长度的一个函数。
3.能力所能达到选拔函数作为参数的函数称之为高阶函数。因为变量能够本着函数,如f=abs;函数的参数能够选用变量,如def add(x,y,f):;所以二个函数大概能够接过另二个函数作为参数,比方:在add函数内部就调用了abs函数f ,return f(x) f(y)

    形参被调用时才会分配内部存款和储蓄器空间

 

1.5.2 函数变量的成效域

  变量的功用域即变量可以知道性,相当于可用范围,平日编制程序语言分为:全局变量(global variable)和某些变量(local variable)。

  • 全局变量:程序开首定义时定义的变量,在函数外界,无缩进,成效域为全部程序
  • 有的变量:在子程序中定义的变量,函数内部,有缩进,成效域是成套子程序

当全局变量与一些变量同名是,在子程序中有些变量起效能,在外部全局变量起成效。

# 首先加载整个函数,调用函数执行函数内部,打印 tom,最后打印 rosename = 'rose'   # 全局def test():    name = 'tom'    # 局部    printtest()printtomrose    

  1. global 关键字

  全局变量的功效域是全体程序,函数内部能够访谈。可是毫无在函数内部希图改良全局变量,那是因为 Python 使用了遮挡(shadowing)的办法去 保护全局变量。大器晚成旦在函数内部纠正,则会在函数内部创建五个一模二样的风华正茂对变量。

name = 'rose'def test():    name = 'tom'        printtest()printtomrose

  从上面例子能够看看,全局变量的值未有改正。然而 Python 是永葆在函数内部改良全局变量的,只必要在变量前边加上叁个 global 关键字就能够:

name = 'rose'def test():    global name    name = 'tom'    printtest()printtomtom

总结:当全局与一些变量名字类似时,函数内部优先读取局地变量。为了更加好所在分全局与局地变量,日常地全局变量名尽量使用大小,局地变量名使用小写。

  2. 内嵌函数

  函数扶助嵌套,即二个函数中嵌套其余二个函数,这种函数叫内嵌函数或内部函数。

name = 'rose'       # def fun1():         #     name = 'tom'    #     def fun2():     #         name = 'lila'       #     fun2()          #     print     #     print         #               # print         # rosetomrose

Tips:里面函数只好在里面调用,外界调用会报 NameError

(1)map()函数

map(卡塔尔(قطر‎是 Python 内置的高阶函数,它选用八个函数 f 和二个list,并通过把函数 f 依次效能在 list 的每一种元素上,得到二个新的 list 并回到。map(卡塔尔国函数不改变原有的 list

  1. 例如

    def f(x):
    return x*x
    print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])#操作函数在前,被操作的list在后
    #结果为 [1, 4, 9, 10, 25, 36, 49, 64, 81]
    

    return 实施后,前面包车型地铁不在推行,且只可以有二个return

参数分类

从大的角度去看,函数的参数分二种:形参(变量名卡塔尔(قطر‎,实参(值)

详见的分裂函数的参数分为二种:

  1. 职位参数                #专门的学问调用:实参加形参地点大器晚成后生可畏对应
  2. 根本字参数          #驷不比舌字调用:位置没有必要固定
  3. 暗许参数
  4. 可变长参数(*args,**kwargs)
  5. 取名第一字参数

任务参数

def foo(x,y,z):#位置形参:必须被传值的参数
    print(x,y,z)

foo(1,2,3) #位置实参数:与形参一一对应

重大字参数

def foo(x,y,z):
    print(x,y,z)

foo(z=3,x=1,y=2)      #正确 实参通过key=value的形式给形参传值
foo(1,z=3,y=2)        #正确 位置参数与关键字参数混用
foo(x=1,2,z=3)        #错误 关键字实参必须在位置实参后面
foo(1,x=1,y=2,z=3)    #错误 不能重复对一个形参数传值

注意:

  1. 根本字实参必得在义务实参前边
  2. 不可能再一次对二个形参数字传送值

暗许参数

def register(name,age,sex='male'): #形参:默认参数
    print(name,age,sex)

register('asb',age=40)
register('a1sb',39)
register('a2sb',30)
register('a3sb',29)

注意:

  1. 暗中同意参数必须跟在非暗许参数后

    def register(sex='male',name,age卡塔尔国: #在概念阶段就能报错

     print(name,age,sex) 
    
  2. 暗许参数在概念阶段就曾经赋值了,并且只在概念阶段赋值三次

  3. 暗中认可参数的值日常定义成不可变类型

非固定参数

若你的函数在概念时不鲜明客户想传入多少个参数,就能够利用非固定参数

第一种: *args

def foo(x,y,*args): #*会把溢出的按位置定义的实参都接收,以元组的形式赋值给args
    print(x,y)
    print(args)

第二种: **kwargs

def stu_register(name,age,*args,**kwargs): # **会把溢出的按关键字定义的实参都接收,以字典的形式赋值给kwargs
    print(name,age,args,kwargs)

stu_register("Alex",22)
#输出
#Alex 22 () {}#后面这个{}就是kwargs,只是因为没传值,所以为空

stu_register("Jack",32,"CN","Python",sex="Male",province="ShanDong")
#输出
# Jack 32 ('CN', 'Python') {'province': 'ShanDong', 'sex': 'Male'}

命名首要字参数

def foo(name,age,*,sex='male',height):  #*后定义的参数为命名关键字参数,这类参数,必须被传值,而且必须以关键字实参的形式去传值
    print(name,age)
    print(sex)
    print(height)
foo('egon',17,height='185')

知识点1:

def foo(name,age=10,*args,sex='male',height,**kwargs):
    print(name)
    print(age)
    print(args)
    print(sex)
    print(height)
    print(kwargs)

foo('alex',1,2,3,4,5,sex='female',height='150',a=1,b=2,c=3)
# 输出
alex
1       ----->age被位置参数填充
(2, 3, 4, 5)
female
150
{'a': 1, 'c': 3, 'b': 2}

知识点2:

def foo(*args):
    print(args)
foo(*(1,2,3,4)) = foo(1,2,3,4)    # 传入元组,1,2,3,4 <=====>*(1,2,3,4) 此时,*=* args=(1,2,3,4)
# 输出
(1, 2, 3, 4)
foo(*['A','B','C','D']) = foo('A','B','C','D')  # 传入列表, 此时,['A','B','C','D']相当于('A','B','C','D')
# 输出
('A', 'B', 'C', 'D')
foo(['A','B','C','D'])     #  传入列表,此时,列表作为输出的元组中的一个元素
# 输出
(['A', 'B', 'C', 'D'],)

知识点3:

def foo(**kwargs):
    print(kwargs)

foo(**{'y': 2, 'x': 1,'a':1}) #foo(a=1,y=2,x=1)   #实参传入字典,此时,{'y': 2, 'x': 1,'a':1}相当于a=1,y=2,x=1

知识点4: 选择大六个实参

def wrapper(*args,**kwargs):
    print(args)
    print(kwargs)

wrapper(1,2,3,a=1,b=2)

知识点5:

def foo(x,y,z):
    print('from foo',x,y,z)
def wrapper(*args,**kwargs):
    # print(args)      #args=(1,)
    # print(kwargs)     #kwargs={'y':3,'z':2}
    foo(*args,**kwargs)  #foo(*(1,),**{'y':3,'z':2}) #foo(1,z=2,y=3)

wrapper(1,z=2,y=3)
# 输出
from foo 1 3 2

  

1.5.3 闭包

  闭包是函数式编制程序中的两个珍视数据布局,Python 中感到只要在一个之中等学园函授数里,对在表面作用域的变量进行引用,那么那一个里面函数正是闭包。

def fun1:    def fun2:        return x * y    return fun2a = fun1         # a 接收的是 fun2() 的内存地址printb = a            # a 相当于调用 fun2# 上述可以简写# res = fun1# print<function fun1.<locals>.fun2 at 0x00000000026F48C8>30

  从位置的例证可以看见,内部函数 fun2()对表面函数 fun1()的变量 x 举行了援引,那么 fun2()就是闭包。

  nonlocal 关键字

  但须求潜心的是不能够在外部函数外面调用内部函数,对表面函数的部分变量只好进展拜谒,不能够改改。

def fun1():    name = 'rose'    def fun2():        name = 'tom'        return name    print    return fun2fun1rose        # 外部函数局部变量 name = ‘rose' 并没有被修改

  假如在中间函数中想矫正外部函数的后生可畏对变量能够用 nonlocal 关键字,可是急需专一的是它不能够改改全局变量。

def fun1():    name = 'rose'    def fun2():        nonlocal name       # 添加 nonlocal 关键字        name = 'tom'        return name    print    return fun2fun1tom     # 外部函数局部变量 name = ‘rose' 已经被修改

(2)reduce()函数

reduce(卡塔尔函数选取的参数和 map(卡塔尔国相似,一个函数 f,一个list,但行为和 map(卡塔尔不一致,reduce(卡塔尔传入的函数 f 必得选拔多个参数,reduce(卡塔尔(英语:State of Qatar)对list的各种成分反复调用函数f,并回到最终结出值。

  1. 例如

    def f(x, y):
    return x   y
    #先计算头两个元素:f(1, 3),结果为4;
    #再把结果和第3个元素计算:f(4, 5),结果为9;
    #再把结果和第4个元素计算:f(9, 7),结果为16;
    #再把结果和第5个元素计算:f(16, 9),结果为25;
    #由于没有更多的元素了,计算结束,返回结果25。
    
  2. reduce(卡塔尔还能选取第1个可选参数,作为计量的开头值。
    reduce(f, [1, 3, 5, 7, 9], 100)#结果为125

    Python中所谓的经过正是没有重回值的函数

四. 局地变量与全局变量

实例:

name = "ShuKe"
def change_name(name):
    print("before change:", name)
    name = "fengfeng"
    print("after change", name)

change_name(name)
print("在外面看看name改了么?", name)

输出

before change: ShuKe
after change fengfeng
在外面看看name改了么? ShuKe

总结:

  • 在子程序中定义的变量称为局地变量,在程序的一方始定义的变量称为全局变量。
  • 全局变量功效域是全部程序,局地变量成效域是概念该变量的子程序。

当全局变量与局部变量同名时:

  • 在概念局地变量的子程序内,局地变量起效用;在任何地方全局变量起效果。

 

1.6 函数即变量

  Python 程序按程序实践,遭遇函数,先加载到到内部存款和储蓄器,唯有当调用函数时,才会运作函数体。由此三个函数能够充作 变量在另三个函数内部调用实践,前提是率先个函数须求先加载。

  首先加载 f1,再调用 f1里的函数体,最后调用 f2里的函数体:

def f1():           #     print('from f1')    #     f2()            # def f2():           #     print('from f2')    #                 # from f1from f2

  另生机勃勃种景况:

def f2():    print('from f2')def f1():    print('from f1')    f2from f1from f2

  第两种情景,调用 f2()时,因为 函数 f2()尚未加载,引致出错(NameError: name 'f2' is not defined):

def f1():    print('from f1')f2:    print('from f2')f1()

(3)filter()函数

filter(卡塔尔(قطر‎函数接纳三个函数 f 和三个list,那些函数 f 的职能是对各类成分进行剖断,再次回到 True或 False,filter(卡塔尔根据剖断结果机关过滤掉不切合条件的要素,重临由切合条件成分结合的新list

  1. 例如

    def is_odd(x):
    return x % 2 == 1
    filter(is_odd, [1, 4, 6, 7, 9, 12, 17])
    #输出为 [1, 7, 9, 17]
    

  参数:

 五. 前向援引之'函数即变量'

def action():
    print 'in the action'
    logger()
action()
报错NameError: global name 'logger' is not defined

def logger():
    print 'in the logger'
def action():
    print 'in the action'
    logger()

action()

def action():
    print 'in the action'
    logger()
def logger():
    print 'in the logger'

action()

  

1.7 递归函数

  在函数内部,能够调用其余函数,若是在调用进程中一直或直接调用自个儿,那么这么些函数正是递归函数。

  递归函数特征:

  • 总得有名扬天下的完工条件
  • 历次步入越来越深一次递归时,难点规模比上叁次都应具备减少
  • 递归功用不高,档案的次序过多轻巧形成 栈溢出

函数调用是经过栈实现,每调用叁回,栈就能够追加生机勃勃层栈帧,函数重回,则收缩后生可畏层。由于栈的轻重有限,全体递归过多,就能够引致栈溢出。

def func:    print    if int == 0:       # 结束条件        return n    res = func   # 调用自身    return resfunc10,5,2,1

(4)sorted()函数

  1. 自定义相比较函数:传扬多少个待相比较的元素 x, y,假如 x 应该排在 y 的前面,重返 -1,假如 x 应该排在 y 的背后,再次来到 1。要是 x 和 y 相等,重返 0。

    def reversed_cmp(x, y):#倒序排序
    if x > y:
        return -1
    if x < y:
        return 1
    return 0
    >>> sorted([36, 5, 12, 9, 21], reversed_cmp)
    [36, 21, 12, 9, 5]
    
# Python中有三种参数:普通参数、默认参数,动态参数(针对形参说)
# 普通参数
# 此外对参数的理解如下:
def test(x,y,z):# 三个都是普通参数
    print(x)
    print(y)
    print(z)
test(1,2,3)# 实参叫位置参数,赋值时 必须一一对应 不能多,也不能少

test(y=1,x=2,z=3) # 关键字参数,不需要一一对应,不能多,也不能少

test(1,2,z=3) # 位置参数必需放在关键字参数左侧,不能多,也不能少
test(1,2,y=3) # 报错,已经对y赋值,在赋值报错


# 默认参数
def handle(x,type='mysql'):
    print(x)
    print(type)
handle('hello') 
handle('hello',type='sqlite')
handle('hello','sqlite')

# 动态参数(也可以叫参数组)
def test(x,*args):
    print(x)
    print(args)

#######      * 与列表有关     ** 与字典有关
#######      *args
def test(x,*args):
    print(x)
    print(args)
test(1)
# 1
# ()
test(1,2,3,4,5)
# 1
# (2, 3, 4, 5)
test(1,{'name':'alex'})
# 1
# ({'name': 'alex'},)
test(1,['x','y','z'])
# 1
# (['x', 'y', 'z'],)
test(1,*['x','y','z'])
# 1
# ('x', 'y', 'z')
test(1,*('x','y','z'))
# 1
# ('x', 'y', 'z')


def test(x,*args):
    print(x)
    print(args)  # 获得元组 通过for遍历传递
    print(args[0])
    print(args[0][0])
# test(1)
# test(1,2,3,4,5)
# test(1,{'1':1})
test(1,['s','a','dd'])
# test(1,*['s','a','dd'])




#######      **args

def test(x,**kwargs):
    print(x)
    print(kwargs)
test(1,y=2,z=3)
test(1,1,2,2,2,2,2,y=2,z=3) # 报错
test(1,y=2,z=3,z=3)#会报错 :一个参数不能传两个值



######## 混合
def test(x,*args,**kwargs):
    print(x)
    print(args,args[-1])
    print(kwargs,kwargs.get('y'))
# test(1,1,2,1,1,11,1,x=1,y=2,z=3) #报错 x
# test(1,1,2,1,1,11,1,y=2,z=3)

test(1,*[1,2,3],**{'y':1})
test(1,*[1,2,3],**{'y':1,'z':2})

 六. 嵌套函数和效能域

看上边的题指标情趣是,函数还可以套函数?当然能够...

name = "Alex"

def change_name():
    name = "Alex2"

    def change_name2():
        name = "Alex3"
        print("第3层打印",name)

    change_name2() #调用内层函数
    print("第2层打印",name)


change_name()
print("最外层打印",name)

#输出
第3层打印 Alex3
第2层打印 Alex2
最外层打印 Alex

效率域在概念函数时就早就定位住了,不会趁机调用地方的改换而改换

# 例一:
name='alex'

def foo():
    name='lhf'
    def bar():
        print(name)
    return bar

func=foo()
func()


# 例二:
name='alex'

def foo():
    name='lhf'
    def bar():
        name='wupeiqi'
        def tt():
            print(name)
        return tt
    return bar

func=foo()
func()

输出

lhf
wupeiqi

 

1.7.1 示例

  递归问路

  使用递归函数,实现三遍递归问路操作。

import timeperson_list = ['rose', 'tom', 'lila', 'json', 'john']def ask_way(person_list):    """    问路操作    :param person_list: 被问的人    :return:    """    print('-'*60)    if len(person_list) == 0:        return '没人知道'    person = person_list.pop()    if person == 'json':        return '%s 我知道 xxx 怎么走,它在 xxx' % person    print('你好,%s,请问 xxx 在哪里?' % person)    print('%s 回答道:我也不知道,我帮你去问问 %s' % (person, person_list))    time.sleep    res = ask_way(person_list)    return resres = ask_way(person_list)print

------------------------------------------------------------你好,john,请问 xxx 在哪里?john 回答道:我也不知道,我帮你去问问 ['rose', 'tom', 'lila', 'json']------------------------------------------------------------json 我知道 xxx 怎么走,它在 xxx

  二分查找

data = [1,3,6,7,9,12,14,16,17,18,20,21,22,23,30,32,33,35]def find_num(data, num):    """    使用二分查找法,查找出一个数字的位置    """    print    if len > 1:        mid = int/2)        if data[mid] == num:            print('找到数字', data[mid])        elif data[mid] > num:            print('要找的数字在 %s 右边' % data[mid])            return find_num(data[0:mid], num)        else:            print('要找的数字在 %s 左边' % data[mid])            return find_num(data[mid 1:], num)    else:        if data[0] == num:            print('找到数字', data[0])        else:            print('要找的数字不在列表中')find_num

[1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]要找的数字在 18 左边[20, 21, 22, 23, 30, 32, 33, 35]要找的数字在 30 左边[32, 33, 35]要找的数字在 33 左边[35]要找的数字不在列表中

(5卡塔尔(قطر‎函数作为重临值

  1. 例如

    def f():
    print 'call f()...'
    # 定义函数g:
    def g():
        print 'call g()...'
    # 返回函数g:
    return g
    >>> x = f()   # 调用f()
    call f()...
    >>> x   # 变量x是f()返回的函数:
    <function g at 0x1037bf320>
    >>> x()   # x指向函数,因此可以调用
    call g()...   # 调用x()就是执行g()函数定义的代码
    

  函数变量:

七. 递归

在函数内部,能够调用其余函数。就算在调用一个函数的经过中央职能部门接或直接调用本身自己

def calc(n):
    print(n)
    if int(n/2) ==0:
        return n
    return calc(int(n/2))

calc(10)

输出:
10
5
2
1

澳门新萄京官方网站 2澳门新萄京官方网站 3

#_*_coding:utf-8_*_
__author__ = 'Linhaifeng'
import time

person_list=['alex','wupeiqi','yuanhao','linhaifeng']
def ask_way(person_list):
    print('-'*60)
    if len(person_list) == 0:
        return '没人知道'
    person=person_list.pop(0)
    if person == 'linhaifeng':
        return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' %person
    print('hi 美男[%s],敢问路在何方' %person)
    print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' %(person,person_list))
    time.sleep(3)
    res=ask_way(person_list)
    # print('%s问的结果是: %res' %(person,res))
    return res



res=ask_way(person_list)

print(res)

递归问路

递归问路

递归性情:

  1. 总得有一个醒目标了断条件

  2. 老是步入越来越深意气风发层递归时,难点规模相比上次递归都应具有减弱

3. 递归成效不高,递归档案的次序过多会促成栈溢出(在微型机中,函数调用是因而栈(stack)这种数据布局落成的,每当步入一个函数调用,栈就能加风华正茂层栈帧,每当函数重回,栈就能减大器晚成层栈帧。由于栈的深浅不是特别的,所以,递归调用的次数过多,会变成栈溢出)

货仓扫除文盲: http://www.cnblogs.com/lln7777/archive/2012/03/14/2396164.html 

尾递归优化:

澳门新萄京官方网站 4澳门新萄京官方网站 5

data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]


def binary_search(dataset,find_num):
    print(dataset)

    if len(dataset) >1:
        mid = int(len(dataset)/2)
        if dataset[mid] == find_num:  #find it
            print("找到数字",dataset[mid])
        elif dataset[mid] > find_num :# 找的数在mid左面
            print("33[31;1m找的数在mid[%s]左面33[0m" % dataset[mid])
            return binary_search(dataset[0:mid], find_num)
        else:# 找的数在mid右面
            print("33[32;1m找的数在mid[%s]右面33[0m" % dataset[mid])
            return binary_search(dataset[mid 1:],find_num)
    else:
        if dataset[0] == find_num:  #find it
            print("找到数字啦",dataset[0])
        else:
            print("没的分了,要找的数字[%s]不在列表里" % find_num)


binary_search(data,66)

二分查找

二分查找

递归私下认可的递归档期的顺序数是:1000

import sys
print(sys.getrecursionlimit())      # 默认递归调用层数
sys.setrecursionlimit(100000)       # 设置递归最大的调用层数
print(sys.getrecursionlimit())
'''
1000
100000
'''

 

1.7.2 尾调用

  尾调用又称作为递归,指的是函数在终极一步调用另叁个函数的长河(最后黄金年代行不料定是终极一步)。

# bar 在 foo 内为尾调用def bar:    return ndef foo:    return bar

# bar 在 foo 内不是尾调用,最后一步为 return ydef bar:    return ndef foo:    y = bar    return y

# bar1、bar2 在 foo 内都是尾调用def bar1:    return ndef bar2:    return n 1def foo:    if type is str:        return bar1    elif type is int:        return bar2

  尾调用优化

  定义 a 函数,a 内调用 b,b 调用 c,在内部存款和储蓄器中产生叁个调用记录,又称作调用帧(call frame)。用于存款和储蓄调用地点和内部变量等音信,即,直至 c 重回结果给 b,c 的调用记录消失。b 再次来到给 a,b 的调用记录消失,a 重返结果,a 的调用记录消失,全体记录都是先进后出,产生一个调用栈(call stack)

(6)闭包

内层函数援用了外围函数的变量(参数也算变量),然后回来内层函数的境况,称为闭包(Closure)。
闭包的风味是回去的函数还引用了外围函数的一些变量,所以,要科学生运动用闭包,将在保障援用的部分变量在函数再次回到后不能够变。

def calc_sum(lst):
    def lazy_sum():
        return sum(lst)
    return lazy_sum

    分为:全局变量、局地变量

八. 佚名函数

  1. 无名氏函数正是无需显式的钦赐函数,程序运转甘休顿时被销毁

语法:

lambda x:y
x为接收值,y为返回值
lambda表达式中不支持if...else...简单的判断

诚如将轻松的函数用lambda表明式格局代替,如下:

#这段代码
def calc(n):
    return n**n
print(calc(10))

#换成匿名函数
calc = lambda n:n**n
print(calc(10))

你可能会说,用上那些东西没认为有毛方便呀, 。。。。呵呵,假设是如此用,确实没毛线修改,可是无名氏函数主假设和别的函数搭配使用的吗,如下:

澳门新萄京官方网站 6澳门新萄京官方网站 7

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

'''
#结果
<function <lambda> at 0x0000000000A4E0D0>
3
'''

示例1

  1. 佚名函数与max,min,zip,sorted的使用格局如下:
    注: max,min,zip,sorted内置函数内部依次迭代传入的靶子

    澳门新萄京官方网站, # 示例所使用的剧情如下所示

    salaries={ 'egon':3000, 'alex':100000000, 'wupeiqi':10000, 'yuanhao':2000 }

澳门新萄京官方网站 8澳门新萄京官方网站 9

print(max(salaries))            # 默认以字典的key作为元素对比
res=zip(salaries.values(),salaries.keys())      # 使用zip函数进行转换,以values作为key,以key作为values进行max求最大值
print(res)          # 一个zip对象
# print(list(res))
print(max(res))     # 最大值根据key来判断,此时res的可以为salarise的values值

'''
yuanhao     # 错误值
<zip object at 0x0000000000A45348>
(100000000, 'alex')
'''

zip和lambda函数

澳门新萄京官方网站 10澳门新萄京官方网站 11

def func(k):
    return salaries[k]
print(max(salaries))        # 默认以key进行对比,输出错误
print(max(salaries,key=func))       # 以key进行对比,同时将key传给函数func,形如:func(key)-->salaries[k],此时salaries[k]对应的是字典中的values,再次进行max求最大值后,获取最大值
print(max(salaries,key=lambda k:salaries[k]))
print(min(salaries,key=lambda k:salaries[k]))
print(sorted(salaries))     # 默认的排序结果是从小到到,默认以key对比
print(sorted(salaries,key=lambda x:salaries[x])) # 根据values作为对比,从小到大排列,输出key
print(sorted(salaries,key=lambda x:salaries[x],reverse=True)) # 设置reverse=True,从大到小

'''
yuanhao         # 错误值
alex
alex
yuanhao
['alex', 'egon', 'wupeiqi', 'yuanhao']
['yuanhao', 'egon', 'wupeiqi', 'alex']
['alex', 'wupeiqi', 'egon', 'yuanhao']
'''

max|min|sorted与lambda函数

  1. 无名函数与map,reduce,filter的应用方式如下:
  • map(卡塔尔(英语:State of Qatar)函数 map(卡塔尔(英语:State of Qatar)是 Python 内置的高阶函数,它选取三个函数 f 和三个list,并透过把函数 f 依次功能在 list 的每一种成分上,得到两个新的 list 并再次回到。

注:map(卡塔尔(قطر‎函数不改善原有的 list,而是重返三个新的 list。

澳门新萄京官方网站 12澳门新萄京官方网站 13

map()函数
map()是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并通过把函数 f 依次作用在 list 的每个元素上,得到一个新的 list 并返回。

例如,对于list [1, 2, 3, 4, 5, 6, 7, 8, 9]

如果希望把list的每个元素都作平方,就可以用map()函数:



因此,我们只需要传入函数f(x)=x*x,就可以利用map()函数完成这个计算:

def f(x):
    return x*x
print map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9])
输出结果:

[1, 4, 9, 10, 25, 36, 49, 64, 81]
注意:map()函数不改变原有的 list,而是返回一个新的 list。

利用map()函数,可以把一个 list 转换为另一个 list,只需要传入转换函数。

由于list包含的元素可以是任何类型,因此,map() 不仅仅可以处理只包含数值的 list,事实上它可以处理包含任意类型的 list,只要传入的函数f可以处理这种数据类型。

任务
假设用户输入的英文名字不规范,没有按照首字母大写,后续字母小写的规则,请利用map()函数,把一个list(包含若干不规范的英文名字)变成一个包含规范英文名字的list:

输入:['adam', 'LISA', 'barT']
输出:['Adam', 'Lisa', 'Bart']


def format_name(s):
    s1=s[0:1].upper() s[1:].lower();
    return s1;

print map(format_name, ['adam', 'LISA', 'barT'])

map函数示例

澳门新萄京官方网站 14澳门新萄京官方网站 15

li=['alex','egon','shuke']

res=map(lambda x:x ' Love me',li)     # 它接收一个函数(lambda)和一个 list,并通过把函数 lambda(可以是任何函数对象,只要能够处理list中的数据) 依次作用在 list 的每个元素上,得到一个新的 list 并返回
print(res)
print(list(res))

'''
<map object at 0x0000000000B64588>
['alex Love me', 'egon Love me', 'shuke Love me']
'''

map与lambda

澳门新萄京官方网站 16澳门新萄京官方网站 17

nums=(2,4,9,10)
res1=map(lambda x:x**2,nums)
print(list(res1))

'''
[4, 16, 81, 100]
'''

示例2

reduce()函数也是Python内置的四个高阶函数。

reduce(卡塔尔(英语:State of Qatar)函数选择的参数和 map(卡塔尔(قطر‎相通,八个函数 f,几个list,但作为和 map(卡塔尔分歧,reduce(卡塔尔(قطر‎传入的函数 f 必需采取几个参数,reduce(卡塔尔(英语:State of Qatar)对list的每一个成分反复调用函数f,并回到最终结果值。

澳门新萄京官方网站 18澳门新萄京官方网站 19

# python3中reduce函数需要导入
from functools import reduce

li=[1,2,3,4,5]
print(reduce(lambda x,y:x y,li))  # 默认的初始值为列表中的第一个元素,即x=li[0],之后会遍历li列表中的每一个元素进行求和操作,从li[1]开始
print(reduce(lambda x,y:x y,li,100))  # 此处10为第一次传入的初始值,即x = 100,之后会遍历li列表中的每一个值进行求和操作,从li[0]开始

'''
15
115
'''

reduce和lambda

filter()函数也是Python内置的贰个高阶函数。

filter(卡塔尔(英语:State of Qatar)函数饱含七个参数,分别是function和list。该函数基于function参数重返的结果是还是不是为真来过滤list参数中的项.

澳门新萄京官方网站 20澳门新萄京官方网站 21

# 示例1
li=['alex-old','wupeiqi-old','yuanhao','egon']
res=filter(lambda x:x.endswith('old'),li)       # x.endswith('old')值为真,则储存元素,list参数中所有为假的元素都将被删除。
print(res)
print(list(res))
'''
<filter object at 0x00000000006D4908>
['alex-old', 'wupeiqi-old']
'''
#示例2
nums=[0,1,2,3,4,5,6,7]
res = filter(None,nums)         # 如果filter参数值为None,就使用identity()函数,list参数中所有为假的元素都将被删除。
print(list(res))
'''
[1, 2, 3, 4, 5, 6, 7]
'''

fliter和lambda

 

1.8 佚名函数

  无名氏函数即不需求体现地钦赐函数名的函数,Python 允许采用 lambda 关键字来创制三个无名氏函数,佚名函数也被称之为 lambda 表达式。

lambda x:x 2lambda x,y,z:(x 1, y 1, z 1)    # 多个参数

  冒号左侧是原函数参数,能够有三个参数,逗号分隔就可以,冒号右侧为再次回到值。对于有个别构造比较轻巧的函数,能够一直定义为佚名函数:

def func:    return x 2s = funcprint

  上述函数可径直定义四个佚名函数:

f = lambda x:x 2f        # 调用

  无名氏函数常与其余函数搭配使用:

# 将 匿名函数当做参数传入 calc 中def calc:    ret = []    for i in li:        res = func        ret.append    return retli = [2, 3, 4, 6, 8]calc(lambda x:x 1, li)[3, 4, 5, 7, 9]

  lambda 表明式的功用:

  • 奉行一些剧本时,省略定义函数进度
  • 对此全体程序只供给进行意气风发两次的函数,不用思量命名难题
  • 简化代码步骤
 1 # 如果函数的内容无global关键字,
 2 #   - 有声明局部变量
 3         # NAME = ["产品经理","廖波湿"]
 4         # def qupengfei():
 5         #     NAME = "自己"
 6         #     print('我要搞', NAME)
 7         # qupengfei()
 8 #   - 无声明局部变量
 9         # NAME = ["产品经理","廖波湿"]
10         # def qupengfei():
11         #     NAME.append('XXOO')
12         #     print('我要搞', NAME)
13         # qupengfei()
14 
15 # 如果函数的内容有global关键字
16 #   - 有声明局部变量
17         # NAME = ["产品经理","廖波湿"]
18         # def qupengfei():
19         #     global NAME
20         #     NAME = "自己"
21         #     print('我要搞', NAME)
22         # qupengfei()
23         # 错误示例
24         # NAME = ["产品经理","廖波湿"]
25         # def qupengfei():
26         #     NAME = "自己"
27         #     global NAME
28         #     print('我要搞', NAME)
29         # qupengfei()
30 #   - 无声明局部变量
31         # NAME = ["产品经理","廖波湿"]
32         # def qupengfei():
33         #     global NAME
34         #     NAME = ["阿毛"]
35         #     NAME.append('XXOO')
36         #     print('我要搞', NAME)
37         # qupengfei()
38 
39 ######## 全局变量变量名大写
40 ######## 局部变量变量名小写
41 
42 
43 # 优先读取局部变量,能读取全局变量,无法对全局变量重新赋值 NAME=“fff”,
44 #     但是对于可变类型,可以对内部元素进行操作
45 # 如果函数中有global关键字,变量本质上就是全局的那个变量,可读取可赋值 NAME=“fff”

 1 NAME = ["产品经理","廖波湿"]
 2 
 3 def yangjian():
 4     # NAME = "史正文"
 5     global NAME # 已经声明,NAME就是全局的的那个变量
 6     print('我要搞', NAME)
 7     NAME = "小东北"  # 修改 全局的变量
 8     print('我要搞', NAME)
 9 yangjian()
10 
11 
12 
13 
14 #### nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
15 
16 
17 
18 name = "刚娘"
19 
20 def weihou():
21     name = "陈卓"
22     def weiweihou():
23         nonlocal name   # nonlocal,指定上一级变量,如果没有就继续往上直到找到为止
24         name = "冷静"
25 
26     weiweihou()
27     print(name)
28 
29 print(name)
30 weihou()
31 print(name)
32 刚娘
33 冷静
34 刚娘

九. 函数式编制程序

函数是Python内建扶植的风流倜傥种包装,大家因此把大段代码拆成函数,通过意气风发层黄金年代层的函数调用,就足以把纷纷职分分解成轻便的职分,这种解释能够称呼面向进度的前后相继设计。函数正是面向进程的主次设计的骨干单元。

函数式编制程序中的函数那个术语不是指Computer中的函数(实际上是Subroutine),而是指数学中的函数,即自变量的映射。也正是说三个函数的值仅决计于函数参数的值,不相信任别的情状。譬如sqrt(x卡塔尔(قطر‎函数计算x的平方根,只要x不改变,无论何时调用,调用一遍,值都以不改变的。

Python对函数式编制程序提供部分援助。由于Python允许利用变量,因而,Python不是纯函数式编程语言。

2. 函数式编制程序

  前向引用

1. 定义

粗略说,"函数式编制程序"是意气风发种"编制程序范式"(programming paradigm),也正是哪些编写程序的方法论。

待补充......

 

2.1 编程论

  当今编制程序的二种方法论:

  • 面向进度:
  • 函数式编程:特征(无变量、函数即变量)
  • 面向对象:

  函数式编制程序,更接近数学,是生机勃勃种浮泛比什凯克异常高的编制程序范式,不容许函数有变量。但 Python 不是严特意义上的函数式编制程序,因为它同意有变量。

  函数式编制程序特点:

  • 函数即变量(叁个函数作为参数字传送入另三个函数)
  • 重回值是函数(能够函数本人,也足以是其他函数)

  函数即变量

def foo:    printdef bar:    printfoo(bar('rose'))roseNone   

  上边例子中,bar 打字与印刷 rose,未有重临值,由此 foo(bar相当于 foo

  再次回到值是函数

  再次回到函数自身:

def handle():    print('from handle')    return handle       # 返回函数本身内存地址h = handle()        # 使用变量 h 接收h()         # 再调用函数本身from handlefrom handle

  再次回到其余函数:

def test():    print('from test')def test1():    print('from test1')    return test     # 返回 test 函数的内存地址n = test1()     # 接收n()      # 相当于调用 test()
 1 ## Python 是先编译后运行
 2 def bar():
 3     print('from bar')
 4 def foo():
 5     print('from foo')
 6     bar()
 7 
 8 foo()
 9 
10 
11 
12 def foo():
13     print('from foo')
14     bar()
15 
16 def bar():
17     print('from bar')
18 foo()
19 
20 
21 
22 报错:不能先调用,后定义 
23 def foo():
24     print('from foo')
25     bar()
26 
27 foo()
28 
29 def bar():
30     print('from bar')

十. 置于函数

澳门新萄京官方网站 22

1、数学生运动算

  abs(), round(),pow(),divmod(),max(),min(),sum()

澳门新萄京官方网站 23澳门新萄京官方网站 24

'''
1、数学运算
'''
# abs(-5)  # 取绝对值,也就是5
# round(2.623423, 4)  # 四舍五入取整,也就是3.0, 4为精准到四位四舍五入
# pow(2, 3)  # 相当于2**3,如果是pow(2, 3, 5),相当于2**3 % 5
# divmod(9, 2)  # 返回除法结果和余数
# max([1, 5, 2, 9])  # 求最大值
# min([9, 2, -4, 2])  # 求最小值
# sum([2, -1, 9, 12])  # 求和

数学生运动算

2、工厂函数

  int(), float(), str(), bool(), slice(), list(), tuple(), dict(), set(), frozenset()

澳门新萄京官方网站 25澳门新萄京官方网站 26

# int("5")  # 转换为整数 integer
# float(2)  # 转换为浮点数 float
# str(2.3)  # 转换为字符串 string
# bool(0)  # 转换为相应的真假值,在Python中,0相当于False在Python中,下列对象都相当于False:[], (), {}, 0, None, 0.0, ''
# slice(5, 2, -1)  # 构建下标对象 slice,切片函数
# list((1, 2, 3))  # 转换为表 list
# tuple([2, 3, 4])  # 转换为定值表 tuple
# dict(a=1, b="hello", c=[1, 2, 3])  # 构建词典 dictionary
# set()          创建集合函数
# frozenset()  创建一个不可修改的集合 如:s=frozenset({1,2}) # 定义不可变集合

工厂函数

3、类型调换

  ord(), chr(), bin(), hex(), oct(), complex()

澳门新萄京官方网站 27澳门新萄京官方网站 28

ord("A")  # "A"字符对应的数值
chr(65)  # 数值65对应的字符
bin(56)  # 返回一个字符串,表示56的二进制数
hex(56)  # 返回一个字符串,表示56的十六进制数
oct(56)  # 返回一个字符串,表示56的八进制数
complex(3, 9)  # 返回复数 3   9j

类型转变

4、连串操作

  all(), any(), sorted(), reversed()

澳门新萄京官方网站 29澳门新萄京官方网站 30

all([True, 1, "hello!"])        # 是否所有的元素都相当于True值
any(["", 0, False, [], None])   # 是否有任意一个元素相当于True值
reversed([1,5,3])               # 返回反序的序列,也就是[3,5,1]

队列操作

5、编写翻译实行函数

  repr(), compile(), eval(), exec()

澳门新萄京官方网站 31澳门新萄京官方网站 32

# repr(me)                         # 返回一个对象的字符串表示。有时可以使用这个函数来访问操作。
# compile("print('Hello')",'test.py','exec')       # 编译字符串成为code对象
# eval("1   1")                     # 解释字符串表达式。参数也可以是compile()返回的code对象
'''
# cmd='print("你瞅啥")'
# 
# dic="{'a':1,'b':2}"
# d=eval(dic)
# print(type(d),d['a'])
# 
# with open('user.db','w',encoding='utf-8') as f:
#     user_dic={'name':'egon','password':'123'}
#     f.write(str(user_dic))
# 
# with open('user.db','r',encoding='utf-8') as f:
#     dic=f.read()
#     print(dic,type(dic))
#     dic=eval(dic)
#     print(dic['name'])
'''
# exec("print('Hello')")            #  exec()执行字符串或complie方法编译过的字符串,没有返回值

编写翻译推行函数

6、辅助函数

  dir(), help(), id(), len(), challables()

澳门新萄京官方网站 33澳门新萄京官方网站 34

'''
6、帮助函数
'''
# dir()  不带参数时返回当前范围内的变量,方法和定义的类型列表,带参数时返回参数的属性,方法列表
'''
l=[]
print(dir(l)) #查看一个对象下面的属性
'''
# help()  返回对象的帮助文档
'''
print(help(l))
'''
# id()  返回对象的内存地址
'''
# x=1
# y=x
# print(id(x),id(y))
#
# print(x is y) #判断的是身份
'''
# len()  返回对象长度,参数可以是序列类型(字符串,元组或列表)或映射类型(如字典)
# challable()  判断对象是否可以被调用,能被调用的对象就是一个callables对象,比如函数和带有__call__()的实例
'''
def func():
    pass
print(callable(func))
'''

扶助函数

7、功效域查看函数

  globals(), locals(), vars()

澳门新萄京官方网站 35澳门新萄京官方网站 36

#globals()  返回一个描述当前全局变量的字典
#locals()  打印当前可用的局部变量的字典
#vars() #等于locals()

效能域查看函数

8、迭代器函数

  iter(), next(), enumerate(), range()#python3中为浮动三个迭代器

澳门新萄京官方网站 37澳门新萄京官方网站 38

'''
8、迭代器函数
'''
'''
iter(o[, sentinel])
返回一个iterator对象。该函数对于第一个参数的解析依赖于第二个参数。
如果没有提供第二个参数,参数o必须是一个集合对象,支持遍历功能(__iter__()方法)或支持序列功能(__getitem__()方法),
参数为整数,从零开始。如果不支持这两种功能,将处罚TypeError异常。
如果提供了第二个参数,参数o必须是一个可调用对象。在这种情况下创建一个iterator对象,每次调用iterator的next()方法来无
参数的调用o,如果返回值等于参数sentinel,触发StopIteration异常,否则将返回该值。
'''
# next()  返回一个可迭代数据结构(如列表)中的下一项
# enumerate()  # 返回一个可以枚举的对象,该对象的next()方法将返回一个元组
# x=range(10)
# enumerate([1,2,3]).__next__()
# range()  根据需要生成一个指定范围的数字,可以提供你需要的控制来迭代指定的次数

迭代器相关函数

9、别的函数

  hash(), filter(), format(), input(), open(), print(), zip(), map(), __import__

澳门新萄京官方网站 39澳门新萄京官方网站 40

# hash() 哈希值用于快递比价字典的键。
# 1. 只要校验的内容一致,那hash得到结果永远一样
# 2. 不可逆
# 3. 只要采用的哈希算法一样,那无论被校验的内容有多长,hash的到的结果长度都一样
# print(hash('asdfasdfsadf'))
# print(hash('asdfasdfsadf'))

# filter()  过滤器,构造一个序列,等价于[ item for item in iterables if function(item)],在函数中设定过滤条件,逐一循环迭代器中的元素,将返回值为True时的元素留下,形成一个filter类型数据
'''
filter(function, iterable)
参数function:返回值为True或False的函数,可以为None。
参数iterable:序列或可迭代对象。
>>> def bigerthan5(x):
...     return x > 5
>>> filter(bigerthan5, [3, 4, 5, 6, 7, 8])
[6, 7, 8]
'''

# format()  #格式化输出字符串,format(value, format_spec)实质上是调用了value的__format__(format_spec)方法
'''
"I am {0}, I like {1}!".format("wang", "moon")
"I am {}, I like {}!".format("wang", "moon")
"I am {name}, I like {msg}!".format(name = "wang", msg ="moon")
'''

# input()  #获取用户输入内容
# open()  打开文件
# print()  输出函数

# zip()  拉链函数将对象逐一配对
# s='helloo'
# l=[1,2,3,4,5]
#
# z=zip(s,l)
# print(z)
# for i in z:
#     print(i)


# import time
# m=__import__('time') #以字符串的形式导入模块
# m.sleep(3000)

'''
map(function, iterable,...)
对于参数iterable中的每个元素都应用fuction函数,并将结果作为列表返回。
如果有多个iterable参数,那么fuction函数必须接收多个参数,这些iterable中相同索引处的元素将并行的作为function函数的参数。
如果一个iterable中元素的个数比其他少,那么将用None来扩展改iterable使元素个数一致。
如果有多个iterable且function为None,map()将返回由元组组成的列表,每个元组包含所有iterable中对应索引处值。
参数iterable必须是一个序列或任何可遍历对象,函数返回的往往是一个列表(list)。

li = [1,2,3]
data = map(lambda x :x*100,li)
print(type(data))
data = list(data)
print(data)

运行结果:

<class 'map'>
[100, 200, 300]
'''

别的函数

10、面向对象使用函数

  super(), isinstance(), issubclass(), classmethod(), staticmethod(), proerty(), delatter(), hasattr(), getattr(), setattr()

澳门新萄京官方网站 41澳门新萄京官方网站 42

#super()  调用父类的方法

# isinstance()  检查对象是否是类的对象,返回True或False
# issubclass()  检查一个类是否是另一个类的子类。返回True或False


# classmethod()  # 用来指定一个方法为类的方法,由类直接调用执行,只有一个cls参数,执行雷的方法时,自动将调用该方法的类赋值给cls.没有此参数指定的类的方法为实例方法
# staticmethod
# property

# delattr()  # 删除对象的属性
# hasattr
'''
hasattr(object,name)
判断对象object是否包含名为name的特性(hasattr是通过调用getattr(object,name))是否抛出异常来实现的。
参数object:对象
参数name:特性名称
>>> hasattr(list, 'append')
True
>>> hasattr(list, 'add')
False
'''
#getattr()  获取对象的属性
#setattr()  与getattr()相对应

面向对象使用函数

11. 平放函数实例

澳门新萄京官方网站 43澳门新萄京官方网站 44

字典的运算:最小值,最大值,排序
salaries={
    'egon':3000,
    'alex':100000000,
    'wupeiqi':10000,
    'yuanhao':2000
}

迭代字典,取得是key,因而比较的是key的最大和最小值
>>> max(salaries)
'yuanhao'
>>> min(salaries)
'alex'

可以取values,来比较
>>> max(salaries.values())
>>> min(salaries.values())
但通常我们都是想取出,工资最高的那个人名,即比较的是salaries的值,得到的是键
>>> max(salaries,key=lambda k:salary[k])
'alex'
>>> min(salaries,key=lambda k:salary[k])
'yuanhao'


也可以通过zip的方式实现
salaries_and_names=zip(salaries.values(),salaries.keys()) 

先比较值,值相同则比较键
>>> max(salaries_and_names)
(100000000, 'alex')

salaries_and_names是迭代器,因而只能访问一次
>>> min(salaries_and_names)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: min() arg is an empty sequence


sorted(iterable,key=None,reverse=False)

多少个放置函数实例

停放参数详细解释: https://docs.python.org/3/library/functions.html?highlight=built#ascii 

 

2.2 高阶函数

  函数式编制程序的四个特点:函数即变量,重返值是函数,只需知足此中三个原则,就能够成为高阶函数。

def add:    return fprint(add(-5, 6, abs))11

  上边例子中,内置函数 abs 作为参数字传送入函数 add。

  递归:

2.2.1 map 函数

  map(function, sequence) 函数是高阶函数的风姿浪漫种,它有多个参数:第三个为函数,另二个收取二个队列。

  其功能是将类别中每一个成分,作为函数参数字传送入第二个参数中,直至类别中各类元素都被循环,回到一个迭代器对象,用 list 可得到结果。

# 对列表 l 中每个元素加 1li = [2, 3, 4, 5, 6]def add_one:    return x 1res = map(add_one, li)printprint)<map object at 0x0000000002C5C0B8>[3, 4, 5, 6, 7]

  上边例子中 map 函数将列表 li 的各个中种种成分抽取,再盛传 add_one 中。

  相符地也可以利用 lambda 表明式与 map 函数简写:

res = map(lambda x:x 1, li)

  传入八个列表:

res = map(lambda x, y: x y, [1, 3, 5], [2, 4, 6])print)

  澳门新萄京官方网站 45

2.2.2 filter 函数

  filter(function or None, iterable)函数有多少个参数:第三个能够是函数也能够是 None,第三个为可迭代对象。

  • 先是个参数为函数:将类别中各种成分抽出作为参数,传入第二个参数中,判别,并把为 True 的值再次来到
  • 第三个参数为 None:将系列中为 True 的因素重临

  第一个参数为函数:

# 过滤掉以 123 结尾的名字names = ['rose_123', 'lila_123', 'john']def filter_123:    return not x.endswith('123')        # 返回没有以 123 结尾的名字res = filter(filter_123, names)listjohn

  使用 lambda 表达式简写:

res = filter(lambda x: not x.endswith('123'), names)list

  第叁个参数为 None:

res = filter(None, [1, 2, 0, True, False])list[1, 2, True]

澳门新萄京官方网站 46澳门新萄京官方网站 47

2.2.3 reduce 函数

  reduce(function, sequence[, initial])函数八个参数:第一个为函数,第贰个为系列,第多个可选为初叶值。

  Python3 把 reduce 函数集成到 functools 模块中,由此老是使用时,须要from functools import reduce。它可以把四个函数效用在三个队列上,这些函数必得选取七个参数。首先将系列中的前多个因素抽取,传入函数中,重回值再与类别中接下去的要素做积存计算,直至系列中的每一个成分都被循环。

  求列表中保有因素的乘积:

  常规:

nums = [1, 2, 3, 100]def reduce_test(func, array):    res = array.pop    for i in array:        res = func    return ress = reduce_test(lambda x,y: x*y, nums)print600

  reduce:

from functools import reducenums = [1, 2, 3, 100]res = reduce(lambda x,y : x*y, nums)print600

  首先将 nums 前四个因素,即 1、2 传到lambda x,y: x*y中,返回 x*y。再将 3 传入,最后将 100 传入,相当于*100)

点名最初值:

from functools import reducenums = [1, 2, 3, 100]res = reduce(lambda x,y : x*y, nums, 6)     # 相当于 *3)*100print3600

  累计总括:

from functools import reducereduce(lambda x,y: x y, [1, 2, 3, 4, 5])15
 1 递归问路:
 2 
 3 import time
 4 
 5 person_list=['alex','wupeiqi','linhaifeng','zsc']
 6 def ask_way(person_list):
 7     print('-'*60)
 8     if len(person_list) == 0:
 9         return '根本没人知道'
10     person=person_list.pop(0)
11     if person == 'linhaifeng':
12         return '%s说:我知道,老男孩就在沙河汇德商厦,下地铁就是' %person
13 
14     print('hi 美男[%s],敢问路在何方' % person)
15     print('%s回答道:我不知道,但念你慧眼识猪,你等着,我帮你问问%s...' % (person, person_list))
16     time.sleep(1)
17     res=ask_way(person_list)
18 
19 
20     print('%s问的结果是: %res' %(person,res))
21     return res
22 
23 res=ask_way(person_list)
24 print(res)

2.2.4 sorted 函数

  排序算法在前后相继中是时常应用的算法,无论是冒泡依旧快排,其基本都是相比较三个因素的轻重。

  • 数字:直白比较
  • 字符串/字典:内需用函数抽象出来比较

  sorted(iterable, key, reverse)函数也是三个高阶函数,在列表内置方法中我们就已经接触到了,它能够对一个列表实行排序,暗中认可从小到大。

sorted([1, -3, 2])[-3, 1, 2]

  其余,它还选择二个 key 函数来自定义排序,key 函数功效在列表中的每一种成分上,再拓宽比较,如按相对值排序:

sorted([1, -3, 2], key=abs)[1, 2, -3]

  第多个参数 reverse,能够反向排序:

sorted([1, -3, 2], key=abs, reverse=True)[-3, 2, 1]

  上边都是指向数字的排序,直接比较其尺寸就可以。然则对于字符串来讲,经常地都以比较其首字母在 ASCII 中的大小:

sorted(['b', 'a', 'Z'])     # 因为在 ASCII中 Z<a['Z', 'a', 'b']

  今后大家不想安分守纪 ASCII 来排序,而是固守字母表排序,那么大家得以通过点名 key 函数,将全体字符串调换为大写或小写就能够兑现:

sorted(['b', 'a', 'Z'], key=str.upper)['a', 'b', 'Z']

递归问路  

2.2.5 偏函数

  functools 模块提供了点不清功能,此中八个正是偏函数。

  当函数的参数个数太多,须要简化时,使用 functools.partial 创制贰个偏函数,那个新的函数能够固定住原函数的局地参数,进而调用更简便易行。

语法布局:

from functools import partialfunc2 = partial(func, *args, **kwargs)  # 第一个参数:要固定的函数,第二个:原函数的位置参数,第三个:关键字参数

  第二个参数能够是自定义的函数,也得以是放置函数。

  int(卡塔尔(英语:State of Qatar) 函数能够把字符串调换为整型,暗中同意依据十进制转变:

>>> int('123')123

  int(卡塔尔国 函数还附加提供一个 base 参数,就算传入 base,就能够做 N 进制转变:

>>> int('123', base=8)      # 按照八进制转换83

停放函数

  若是要转移大量的二进制字符串,每一遍都要传播 base,就能够很麻烦。我们得以应用偏函数将 base=2 固定住,定义二个新的函数,每便只必要传入要转移的字符串就能够:

>>> from functools import partial>>> int2 = partial(int, base=2)     # 将 base = 2 固定住>>> int2('100')     # 相当于 kw={'base': 2}  int('100', **kw)4

自定义函数

  当大家调用有些函数,已知有些参数的值时,可以将其一定住:

from functools import partialdef add:    return x % yadd2 = partial  # 自动将 5 作为 *args 的一部分放在最左边,也就是 5 % 100print)# 101

  递归特性:

2.2.6 练习

  将列表知命之年纪低于等于 18 岁的人过滤出来。

people = [    {'name': 'rose', 'age': 18},    {'name': 'lila', 'age': 30},    {'name': 'tom', 'age': 60}]res = filter(lambda p: p.get('age') <= 18, people)print)[{'name': 'rose', 'age': 18}]

    1. 亟须有五个明明的收尾条件

3. 放权函数

  函数分为 Python 内置函数和自定义函数,内置函数有成都百货上千,不过真的能用到的也少之又少。

# abs():求一个数字的绝对值>>> abs5# all:判断序列中所有元素是否为 True,如果序列为空,也返回 True,返回布尔值>>> all([1, 2, 0])False# any:序列中元素 bool,只要有一个为 True,则返回 True,如果序列为空,返回 False>>> anyFalse>>> any(['', 0, 1])True# bin:十进制转二进制>>> bin'0b1010'# hex:十进制转十六进制>>> hex'0xa'# bool():转换为布尔类型>>> boolFalse>>> boolFalse>>> bool('')False# bytes(obj,encoding=None):将对象编码# bytes(obj,encoding=None).decode:解码,用什么编码就应用什么解码>>> name = '你好'>>> bytes(name, encoding='utf-8')b'xe4xbdxa0xe5xa5xbd'>>> bytes(name, encoding='utf-8').decode('utf-8')'你好'# chr:返回一个数字在 ASCII 中对应的值>>> chr'Z'# ord:查询一个字符咋 ASCII 中的对应的数字>>> ord('Z')90# dict():创建一个字典>>> d = dict()>>> type<class 'dict'># dir:返回一个对象的所有方法名字>>> dir# help:查看帮助文档>>> help(list.append)Help on method_descriptor:append    L.append -> None -- append object to end    # dirmod:返回一个元组,结果为 x/有的商和余数,一般用作网页分页>>> divmod# id:查看一个对象的内存地址>>> id1750035808# globals():查看全局变量# locals():查看局部变量# pow:幂运算,z 可选, pow相当于 %z>>> pow1000>>> pow0# reversed:反转一个序列>>> list(reversed('abc'))['c', 'b', 'a']>>> list(reversed([1, 2, 3]))[3, 2, 1]# round(number,ndigits):四舍五入,保留几位有效小数>>> round4>>> round4.56# set:转换成集合、创建一个集合>>> set('123'){'2', '3', '1'}>>> s = set()>>> type<class 'set'># slice(statr,stop[,step]):序列切片/分片>>> l = 'hello'>>> s = slice>>> l[s]'l'# str():转换为字符串>>> str'123'# sum(iterable, start=0):求序列中所有元素的和,还可指定>>> l = [1, 2, 3, 4]>>> sum10>>> sum11# tuple():转换为元组>>> tuple(['a', 1])('a', 1)# vars:返回对象的属性和属性值的字典对象。>>> vars(){'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' >, 'name': '你好', 'd': "{'name:': 'rose'}", 's': slice(2, 3, None), 'p': {'name': 'rose', 'age': 18, 'gender': 'male'}, 't': <zip object at 0x0000000002D9FF08>, 'i': ('c', 3), 'age': {'rose': 18, 'tom': 19}, 'li': 'hello', 'l': [1, 2, 3, 4]} >>> vars ....  # __import__():当模块名是字符串是,可以使用。 >>> module_name = 'test'>>> __import__(module_name)<module 'test' from 'C:\Users\HJ\Anaconda3\lib\test\__init__.py'>>>> import module_nameTraceback (most recent call last):  File "<stdin>", line 1, in <module>ModuleNotFoundError: No module named 'module_name'

  1. eval()

  eval(expression,[globals[,locals]),用于执行一个字符串表明式,并再次回到表达式值,能够去掉字符串的引号

>>> d = "{'name:': 'rose'}">>> type<class 'str'>>>> s = eval>>> type<class 'dict'>

  字符串中表明式的值,也足以估测计算:

>>> express = '1*2 3'>>> eval5

  2. hash()

  hash做哈希运算,不管对象有多少长度,经过哈希运算后的值长度都生龙活虎律,也不能够依据hash 值反推出原始对象。

  可用于核查软件/文件是不是被别人窜改,还可用来判定软件或文件是或不是下载完整(查证官方给出的 hash 值与和煦下载实现 hash 的值是还是不是雷同)

  • 可哈希数据类型:即不可变数据类型,如:字符串、元组
  • 不可哈希数据类型:即可变数据类型,如:列表、字典、集结
>>> hash('abc')5994226220732616244>>> hash('123')-3466646395452377901

  3. isinstance

  八个都是用以判别数据类型,官方提出使用 isinstance。

>>> type<class 'int'>nums = '123'if type is str:    res = int   1

  isinstance(x,A_tuple)有五个参数:第三个是待明确项指标数据,第贰个是钦命七个数据类型,推断双方是不是相仿,重临叁个布尔值。

>>> isinstanceTrue

  4. zip()

  zip(ite1[,iter2[...]])函数接受多少个连串,供给它们成分数据相等,重返八个系列成分风流浪漫风流倜傥对应的元组(重返的是 zip 对象的内存地址)。

>>> p = {'name': 'rose', 'age': 18, 'gender': 'male'}>>> t = zip, p.values>>> list[('name', 'rose'), ('age', 18), ('gender', 'male')]>>> list(zip(['a', 'b', 'c'], [1, 2, 3]))[('a', 1), ('b', 2), ('c', 3)]>>> for i in zip(['a', 'b', 'c'], [1, 2, 3]):...     print...('a', 1)('b', 2)('c', 3)

  5. max

  max(iterable, key, default)、min()重回叁个行列中的最大、小成分。

  特性:

  • 规律是将类别中各种元素都循环遍历出来相比
  • 第一相比较第叁个字符,分出大小则停止比较,若分出,钻继续比较。区别数据类型不可能比较
  • 字典相比较,私下认可比较 key
>>> max([1, 2, 3])                                       3                                                        >>> max(['a', 'b'])                                      'b'                                                      >>> max(['a12', 'a2'])                 # a 相同,2>1               'a2'                                   # b>a                   >>> max(['a12', 'b10'])                                  'b10'                                                             >>> age = {'rose': 18, 'tom': 19}      # 字典比较默认比较 key                  >>> max                                             'tom'                                          >>> max(zip(age.values(), age.keys        #  既比较大小,又把名字也打印出来                                        (19, 'tom')                                              

  max()还足以内定比较艺术:

# 取出 age 比较>>> people = [    {'name': 'rose', 'age': 18},    {'name': 'lila', 'age': 30},    {'name': 'tom', 'age': 60}]>>> max(people, key=lambda dic:dic.get('age')){'name': 'tom', 'age': 60}

    2. 每趟步向越来越深风姿洒脱层递归时,难题规模比较上次递归都应持有减少

    3. 递归作用不高,递归等级次序过多会促成栈溢出(在微型机中,函数调用是透过栈(stack)这种数据构造完结的,

     每当进入二个函数调用,栈就能加豆蔻梢头层栈帧,每当函数重临,栈就能够减风度翩翩层栈帧。由于栈的尺寸不是十二万分的,

     所以,递归调用的次数过多,会招致栈溢出)

澳门新萄京官方网站 48澳门新萄京官方网站 49

 1 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
 2 
 3 
 4 def binary_search(dataset, find_num):
 5     print(dataset)
 6 
 7     if len(dataset) > 1:
 8         mid = int(len(dataset) / 2)
 9         if dataset[mid] == find_num:  # find it
10             print("找到数字", dataset[mid])
11         elif dataset[mid] > find_num:  # 找的数在mid左面
12             print("33[31;1m找的数在mid[%s]左面33[0m" % dataset[mid])
13             return binary_search(dataset[0:mid], find_num)
14         else:  # 找的数在mid右面
15             print("33[32;1m找的数在mid[%s]右面33[0m" % dataset[mid])
16             return binary_search(dataset[mid   1:], find_num)
17     else:
18         if dataset[0] == find_num:  # find it
19             print("找到数字啦", dataset[0])
20         else:
21             print("没的分了,要找的数字[%s]不在列表里" % find_num)
22 
23 
24 binary_search(data, 66)
25 
26 
27 
28 
29 ##### 结果
30 [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35]
31 找的数在mid[18]右面
32 [20, 21, 22, 23, 30, 32, 33, 35]
33 找的数在mid[30]右面
34 [32, 33, 35]
35 找的数在mid[33]右面
36 [35]
37 没的分了,要找的数字[66]不在列表里

二分法

   

  作用域:

     函数的功用域只跟函数申明时定义的作用域有关,跟函数的调用地方无任何关系  

 1 name = 'jack'
 2   
 3 def foo():
 4     name = 'jerry'
 5     def bar():
 6         name = 'lucy'
 7         print(name)
 8         def tt():
 9             print(name)
10         return tt
11     return bar
12 
13 func = foo() # 得到的是bar()函数的内存地址
14 func()() # 执行bar() 函数
15 # 可以直接foo()()()

  无名函数:

    无名氏函数正是没有必要突显的钦命函数名。情势:lambda x:x 1   

 1 如下代码:
 2 def calc(x):
 3     return x 1
 4 calc(10)
 5 
 6 用匿名函数表示:
 7 func = lambda x:x 1
 8 print(func(10))
 9 
10 
11 
12 def test(x,y,z):
13      return x 1,y 1  #----->(x 1,y 1)
14 
15 匿名函数表示:
16 lambda x,y,z:(x 1,y 1,z 1)

    匿名函数主要用于和其他函数的搭配:

1 l=[3,2,100,999,213,1111,31121,333]
2 print(max(l))
3 
4 dic={'k1':10,'k2':100,'k3':30}
5 
6 
7 print(max(dic))
8 print(dic[max(dic,key=lambda k:dic[k])])

 1 res = map(lambda x:x**2,[1,5,7,4,8])
 2 for i in res:
 3     print(i)
 4 
 5 输出
 6 1
 7 25
 8 49
 9 16
10 64

 

  函数式编制程序:

    编程方法论:面向进度、面向对象、函数式

    面向进程:不问可以预知固然从未再次来到值,风流倜傥层生机勃勃层的往下传递,直到实现须要

    面向对象:把构成难题工作分解成各类对象,建设构造目的的目标不是为着产生叁个步骤,而是为了描叙有些事物在全部祛除难点的手续中的行为

    比如五子棋:

      面向进度:1、伊始游戏,2、黑子先走,3、绘制画面,4、判定输赢,5、轮到白子,6、绘制画面,7、决断输赢,8、重返步骤2,9、输出最终结果。

      面向对象:1、黑白两方,那双方的作为是大同小异的,2、棋盘系统,负担绘制画面,3、法规种类,担任决断诸如犯规、输赢等。

   什么是函数式编程:函数式=编程语言定义的函数   数学意义的函数
        通俗来讲,函数式就是利用编程语言实现数学函数,这种函数内对象是永恒不变的,要么返回值是函数,要么参数是函数,
        没有for和while循环,所有的循环都用递归实现,没有变量赋值,即不改变。但是可读性低,很精简。
        

澳门新萄京官方网站 50澳门新萄京官方网站 51

 1 一、不可变:没有变量,也就没有赋值和修改
 2 # 非函数式:
 3 a=1
 4 def foo():
 5     global a # 尽量啥用
 6     a = 2
 7     return a
 8 foo()
 9 print a
10 
11 # 函数式
12 a = 1
13 def foo():
14     return a 1
15 foo()
16 print a                
17 
18 ###高阶函数  1、函数接收的参数是一个函数名  2、返回值中包含函数
19 ###满足之一就是高阶函数
20 
21 二、函数即变量,把函数当做参数传递给另一个函数
22 def foo(n): #n=bar
23     print(n)
24 
25 def bar(name):
26     print('my name is %s' %name)
27 
28 foo(bar)
29 foo(bar()) #报错
30 foo(bar('alex'))
31 
32 
33 三、返回值中包含函数
34 def bar():
35     print('from bar')
36 def foo():
37     print('from foo')
38     return bar
39 n=foo()
40 n()
41 
42 
43 def hanle():
44     print('from handle')
45     return hanle
46 h=hanle()
47 h()
48 
49 
50 
51 def test1():
52     print('from test1')
53 def test2():
54     print('from handle')
55     return test1()

函数式编制程序样例解析

澳门新萄京官方网站 52澳门新萄京官方网站 53

 1 四、尾调用:在函数的最后一步调用另一个函数(最后一行不一定是函数的最后一步)
 2 # 函数bar在foo内是尾调用
 3 def bar(n):
 4     return n 
 5 def foo(x):
 6     return bar(x)
 7 
 8 # 函数bar1和bar2在foo内是尾调用,二者在if判断条件不同的情况下都有可能作为函数的最后一步
 9 def bar1(n):
10     return n
11 def bar2(n):
12     return n 1
13 
14 def foo(x):
15     if type(x) is str:
16         return bar1()
17     else:
18         return bar2()
19 
20 
21 # 函数bar在foo内不是尾调用
22 def bar(n):
23     return n 
24 def foo(x):
25     y = bar(x)
26     return y
27 
28 # 函数bar在foo内不是尾调用
29 def bar(n):
30     return n 
31 def foo(x):
32     return bar(x)  1 # 先执行bar(x)完了还要执行 1操作 所以不是最后一步

函数式编制程序样例解析2

澳门新萄京官方网站 54澳门新萄京官方网站 55

 1 背景:最后一步调用递归,不要不保存上一次的状态,直接进入下一次递归
 2 
 3 非尾递归
 4 def foo(seq):
 5     if len(seq) == 1:
 6         return seq[0]
 7     head,*tail=seq
 8     return head   foo(tail) #每次都用head保存状态
 9 print(foo(range(100)))
10 
11 尾递归
12 def cal(l):
13     print(l)
14     if len(l) == 1:
15         return l[0]
16     first,second,*args=1
17     1[0]=first*second
18     l.pop(1)
19     return cal(l)

尾递归优化例子

        高阶函数:(map。filter。reduce.....)

澳门新萄京官方网站 56澳门新萄京官方网站 57

 1 #高阶函数 1、函数接收的参数是一个函数名  2、返回值中包含函数
 2 # 满足其一即可
 3 # 把函数当作参数传给另外一个函数
 4 # def foo(n): #n=bar
 5 #     print(n)
 6 #
 7 # def bar(name):
 8 #     print('my name is %s' %name)
 9 #
10 # foo(bar)
11 # foo(bar())
12 # foo(bar('alex'))
13 
14 #返回值中包含函数
15 # def bar():
16 #     print('from bar')
17 # def foo():
18 #     print('from foo')
19 #     return bar
20 # n=foo()
21 # n()
22 
23 def hanle():
24     print('from handle')
25     return hanle
26 h=hanle()
27 h()
28 
29 def test1():
30     print('from test1')
31 def test2():
32     print('from handle')
33     return test1()

View Code

        map函数: 

           map(卡塔尔(英语:State of Qatar)是 Python 内置的高阶函数,它接收一个函数 f 和一个 list,并由此把函数 f 依次作用在 list 的各种成分上,获得四个新的 list 并赶回。

澳门新萄京官方网站 58澳门新萄京官方网站 59

 1 num_l = [1, 2, 10, 5, 3, 7]
 2 def map_test(func, array):  # func=lambda x:x 1    arrary=[1,2,10,5,3,7]
 3     ret = []
 4     for i in array:
 5         res = func(i)  # add_one(i)
 6         ret.append(res)
 7     return ret
 8 print(map_test(lambda x: x   1, num_l))
 9 
10 res = map(lambda x: x   1, num_l) 
11 
12 ## 上面就是map函数的功能,map得到的结果是可迭代对象
13 print('内置函数map,处理结果', res)
14 print('内置函数map,处理结果', list(res))
15 
16 结果:
17 [2, 3, 11, 6, 4, 8]
18 内置函数map,处理结果 <map object at 0x002809F0>
19 内置函数map,处理结果 [2, 3, 11, 6, 4, 8]
20 
21 
22 map后面的参数是一个可迭代对象,执行map时,相当于执行一个for循环
23 
24 print(list(map(lambda x:x 's','12123123')))
25 #['1s', '2s', '1s', '2s', '3s', '1s', '2s', '3s']
26 
27 print(list(map(lambda x:x 's',{'a':1,'b':2})))
28 # ['as', 'bs']

map函数

澳门新萄京官方网站 60澳门新萄京官方网站 61

 1 num_l = [1, 2, 10, 5, 3, 7]
 2 def map_test(func, array):  # func=lambda x:x 1    arrary=[1,2,10,5,3,7]
 3     ret = []
 4     for i in array:
 5         res = func(i)  # add_one(i)
 6         ret.append(res)
 7     return ret
 8 print(map_test(lambda x: x   1, num_l))
 9 
10 res = map(lambda x: x   1, num_l) 
11 
12 ## 上面就是map函数的功能,map得到的结果是可迭代对象
13 print('内置函数map,处理结果', res)
14 print('内置函数map,处理结果', list(res))
15 
16 结果:
17 [2, 3, 11, 6, 4, 8]
18 内置函数map,处理结果 <map object at 0x002809F0>
19 内置函数map,处理结果 [2, 3, 11, 6, 4, 8]
20 
21 
22 map后面的参数是一个可迭代对象,执行map时,相当于执行一个for循环
23 
24 print(list(map(lambda x:x 's','12123123')))
25 #['1s', '2s', '1s', '2s', '3s', '1s', '2s', '3s']
26 
27 print(list(map(lambda x:x 's',{'a':1,'b':2})))
28 # ['as', 'bs']

map函数

        -注-:

          map(卡塔尔国函数不改换原有的 list,而是重回三个新的 list。

         利用map()函数,可以把一个 list 转换为另一个 list,只需要传入转换函数。

               由于list包含的元素可以是任何类型,因此,map() 不仅仅可以处理只包含数值的 list,事实上它可以处理包含任意类型的 list,只要传入的函数f可以处理这种数据类型。

 

澳门新萄京官方网站 62澳门新萄京官方网站 63

1 def format_name(s):
2     # s1=s[0:1].upper() s[1:].lower();
3     s1 = s.capitalize()
4     return s1;
5 
6 print(map(format_name, ['adam', 'LISA', 'barT']))
7 print(list(map(format_name, ['adam', 'LISA', 'barT'])))

map完结输入的名字首字母大写

 

       filter函数:

         filter(卡塔尔(قطر‎函数是 Python 内置的另多少个卓有功效的高阶函数,filter(卡塔尔函数选择多少个函数 f 和多个list,那几个函数 f 的据守是对各种成分举行判别,重回 True或 False,filter(卡塔尔(英语:State of Qatar)根据推断结果自动过滤掉不适合条件的因素,返回由契合条件成分构成的新list。

澳门新萄京官方网站 64澳门新萄京官方网站 65

 1 movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb']
 2 # def sb_show(n):
 3 #     return n.endswith('sb')
 4 #--->lambda n:n.endswith('sb')
 5 
 6 def filter_test(func,array):
 7     ret=[]
 8     for p in array:
 9         if not func(p):
10                ret.append(p)
11     return ret
12 
13 res=filter_test(lambda n:n.endswith('sb'),movie_people)
14 print(res)
15 
16 #filter函数
17 movie_people=['alex_sb','wupeiqi_sb','linhaifeng','yuanhao_sb']
18 print(filter(lambda n:not n.endswith('sb'),movie_people))
19 #<filter object at 0x01CFC850>
20 print(list(filter(lambda n:not n.endswith('sb'),movie_people)))
21 #['linhaifeng']

filter()函数

         -注-:

            filter()函数对list中的每三个因素带入f函数进行演算,保留重返构造为确实成分。

        reduce函数:

          reduce(卡塔尔函数接纳的参数和 map(卡塔尔(英语:State of Qatar)相符,叁个函数 f,三个list,但作为和 map(卡塔尔(قطر‎不一致,reduce(卡塔尔(英语:State of Qatar)传入的函数 f 必须接收七个参数,reduce(卡塔尔(قطر‎对list的各类成分反复调用函数f,并赶回最终结果值。

 

澳门新萄京官方网站 66澳门新萄京官方网站 67

 1 num_l=[1,2,3,100]
 2 def reduce_test(func,array,init=None):
 3     if init is None:
 4         res=array.pop(0)
 5     else:
 6         res=init
 7     for num in array:
 8         res=func(res,num)
 9     return res
10 
11 print(reduce_test(lambda x,y:x*y,num_l,100))
12 
13 
14 #reduce函数
15 # 使用reduce()函数先导入模块
16 from functools import reduce
17 num_l=[1,2,3,100]
18 print(reduce(lambda x,y:x y,num_l,1)) #可以定义起始值,否则默认起始值为第一个元素
19 print(reduce(lambda x,y:x y,num_l))

reduce()函数

      小结:

 

澳门新萄京官方网站 68澳门新萄京官方网站 69

 1 #map()处理序列中的每个元素,得到的结果是一个‘列表’,该‘列表’元素个数及位置与原来一样
 2 #
 3 
 4 #filter遍历序列中的每个元素,判断每个元素得到布尔值,如果是True则留下来
 5 
 6 people=[
 7     {'name':'alex','age':1000},
 8     {'name':'wupei','age':10000},
 9     {'name':'yuanhao','age':9000},
10     {'name':'linhaifeng','age':18},
11 ]
12 print(list(filter(lambda p:p['age']<=18,people)))
13 
14 
15 #reduce:处理一个序列,然后把序列进行合并操作
16 from functools import reduce
17 print(reduce(lambda x,y:x y,range(100),100))
18 print(reduce(lambda x,y:x y,range(1,101)))

小结

 

 

 

    

  

本文由澳门新萄京官方网站发布于www.8455.com,转载请注明出处:澳门新萄京官方网站学习笔记,高阶函数

关键词: