威尼斯人线上娱乐

函数(一)

27 3月 , 2019  

概念函数:

函数(一),函数(

概念函数:

 

#语法
def 函数名(参数1,参数2,参数3,...):
    '''注释'''
    函数体
    return 返回的值

#函数名要能反映其意义

进度:就是没有重临值的函数

 

 

函数的参数:

  • 形参:唯有在被调用时才分配内部存款和储蓄器单元,在调用停止时,马上释放所分配的内部存款和储蓄器单元。因而,形参只在函数内部有效。
  • 实参:能够是常量、变量、表明式、函数等,在实行函数调用时,都无法不有明确的值,以便把那个值传给形参。 

 

威尼斯人线上娱乐 1

 

def test(x,y,z): #x=1,y=2,z=3
    print(x)
    print(y)
    print(z)

#位置参数,必须一一对应,缺一不行多一也不行
test(1,2,3)

#关键字参数,无须一一对应,缺一不行多一也不行
test(y=1,x=2,z=3)

#输出结果:
1
2
3
2
1
3

 

 

#参数组:**字典 *列表
def test(x,*args,**kwargs):
    print(x)
    print(args,args[-1])
    print(kwargs,kwargs.get('s'))
test(1,*[1,2,3],**{'s':1})

#输出结果:
1
(1, 2, 3) 3
{'s': 1} 1

 

本节内容

1. 函数

  函数是团队好的,可重复使用的,用来兑现单一,或有关职能的代码块。

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

  • 代码重用
  • 维持代码一致性,易维护
  • 可拓展

 

全局变量和局地变量:

在子程序中定义的变量称为局地变量,在程序的一起先定义的变量称为全局变量。

全局变量效率域是全部程序,局地变量功用域是概念该变量的子程序。
当全局变量与部分变量同名时:在概念局地变量的子程序内,局地变量起效果;在另各市方全局变量起成效。
 

name='reese'
def change_name():
    print('我的名字',name)
change_name()


def change_name():
    name='帅'
    print('我的名字',name)
change_name()
print(name)


def change_name():
    global name
    name='帅'
    print('我的名字',name)
change_name()
print(name)

#输出结果:
我的名字 reese
我的名字 帅
reese
我的名字 帅
帅

 #
如若函数内部无global关键字,优先读取局地变量,能读取全局变量,不可能对全局变量重新赋值;

   
但对于可变类型(除数字、字符串、元祖,其余都可变),可对内部因素实行操作。

# 假使函数内部有global关键字,变量本质上是全局变量,可读取可赋值。

# 一般全局变量名用大写,局地变量名用小写。

 

  1. 函数基本语法及特点

  2. 参数与部分变量

  3. 返回值

1.1 定义和调用函数

  使用 def
关键字定义1个函数,前面紧跟函数名,小括号也不可或缺,语法如下:

def func():    函数体

  函数在举行时,首先将函数体加载到解释器中,可是不会运作,唯有当调用函数后才会进行,函数名+小括号即可调用函数:

def func():    函数体func()      # 调用函数  
#语法
def 函数名(参数1,参数2,参数3,...):
    '''注释'''
    函数体
    return 返回的值

#函数名要能反映其意义

 

嵌套函数

1.2 返回值

  有时大家必要函数重临一些数码来告诉执行的结果,全部就供给有重回值,只要求在函数中添加
return 关键字,前面跟着再次回到值即可。

def func():    return 1

  return
将再次来到值传递给函数自己,大家要是调用函数,再将函数赋值给变量即可取得再次来到值:

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

函数(一)。  重回值能够是 0 个,也足以是 1 个 或四个:

  • 从未有过重临值,重返 None
  • 3个重临值,重回 重回值
  • 七个再次来到值,重回3个元组

def func():    # return    # return 1    return 1, 2res = func()printNone1

进度:就是从未再次回到值的函数

递归 

#递归调用

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


calc(10)

#输出:
10
5
2
1

 

递归性子:

  1. 必须有一个同理可得的扫尾条件

  2. 老是进入更深一层递归时,难点规模比较上次递归都应负有削减

3.
递归功效不高,递归层次过多会造成栈溢出(在处理器中,函数调用是因此栈(stack)那种数据结构完结的,

每当进入二个函数调用,栈就会加一层栈帧,每当函数重回,栈就会减一层栈帧。由于栈的轻重缓急不是最佳的,所以,递归调用的次数过多,会造成栈溢出)

 

#问路

import time

person_list=['林克','士官长','奎爷','但丁']
def ask_way(person_list):
    print('-'*60)
    if len(person_list) == 0:
        return '没人知道'
    person=person_list.pop(0)
    if person == '但丁':
        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)

 

4.递归

1.3 函数参数

  函数的参数能够用函数达成天性化,大概分成两类:

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

  形参唯有在调用时才分配内部存款和储蓄器单元,调用结束,就释放。仅在函数内部有效,不可能在函数外部使用。

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

 

函数功用域

 

功能域在概念函数时就曾经稳定住了,不会随着调用地方的改观而改变

name = "reese"
def s():
    name = "neo"
    def n():
        print(name)
    return n

func = s()
func()

#输出:
neo

 

5.匿名函数

1.3.1 暗许参数

  形参又分为:暗许参数、地点参数、关键字参数以及可变长参数,而暗中认可参数即在函数定义时暗许赋予有个别形参一个值。若函数调用时,不扩散实参,函数使用私下认可值,不然使用实参。

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

 

 

6.函数式编制程序介绍

1.3.2 地点参数和第③字参数

  普通的参数即为地点参数,在调用时实参必须与形参一一对应。而首要字参数,能够不用考虑地点的涉嫌,只必要名字同样即可。

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

Tips:岗位参数必须在首要字参数前边

函数的参数:

匿名函数:

不需求彰显的内定函数

def calc(x):
    return x + 10


res = calc(10)
print(res)

#输出:
20


#用匿名函数:
func = lambda x: x + 10
print(func(10))

#输出:
20

 

func = lambda x, y, z: x + y + z
print(func(1, 2, 3))

#输出:
6

 

 

7.高阶函数

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

  星号既可用来收集打包参数,也得以用来“解包”参数。当传入的参数时列表、元组、字典以及汇集时,可变长参数将会将其全体打包成唯有1个元组的参数,而在其前方添加2个星号,就能够将里面包车型大巴成分一个个都解出来。

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

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

**kwargs

  另一种可变长参数正是
**kwargs,它将盛传的实参打包成1个字典,同样地也支撑 “解包”。

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}
  • 形参:唯有在被调用时才分配内部存款和储蓄器单元,在调用结束时,登时释放所分配的内存单元。因而,形参只在函数内部有效。
  • 实参:能够是常量、变量、表明式、函数等,在展开函数调用时,都必须有分明的值,以便把这一个值传给形参。 

 

8.平放函数

1.4 函数文书档案

  函数文书档案即用来讲述函数功效的文书档案,能够让别人更好地驾驭您的函数,定义函数文书档案是个好的习惯。

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

 

map函数:

 

num = [3, 4, 5, 6, 11, 7, 54]
#lambda x:x+1
def add_one(x):   #列表元素自增一
    return x + 1

#lambda x:x-1
def minus_one(x):  #列表元素自减一
    return x - 1


def map_test(func, array):
    ret = []
    for i in num:
        res = func(i)
        ret.append(res)
    return ret
print(map_test(add_one,num))
# print(map_test(lambda x:x+1,num)) #可用匿名函数
print(map_test(minus_one,num))
# print(map_test(lambda x:x-1,num))


#终极版本
def map_test(func,array):
    ret = []
    for i in array:
        res = func(i)
        ret.append(res)
    return ret

print(map_test(lambda x:x+1,num))

#输出结果:
[4, 5, 6, 7, 12, 8, 55]
[2, 3, 4, 5, 10, 6, 53]
[4, 5, 6, 7, 12, 8, 55]

 

 map:

拍卖系列中的各样成分,获得的结果是二个列表,该列表成分个数及岗位与原先一样

num = [3, 4, 5, 6, 11, 7, 54]
res=map(lambda x:x+1,num)
print('内置函数map,处理结果',list(res))

print(list(map(minus_one,num)))

msg = "reese"
print(list(map(lambda x:x.upper(),msg)))

#输出结果:
内置函数map,处理结果 [4, 5, 6, 7, 12, 8, 55]
[2, 3, 4, 5, 10, 6, 53]
['R', 'E', 'E', 'S', 'E']

 

 

1.5 函数变量

威尼斯人线上娱乐 2

filter函数:

便宜种类中的每一种成分,判断每一种成分获得布尔值,如若是True则留下来

people = ['reese', 'neo_s', '林克']
print(filter(lambda n: not n.endswith('s'), people))

res = filter(lambda n: not n.endswith('s'), people)
print(list(res))

print(list(filter(lambda n: not n.endswith('s'), people)))

#输出:
<filter object at 0x04E612B0>
['reese', '林克']
['reese', '林克']

 

 

1.函数中央语法及特点

何以不另行代码,其实很简短,只需求把重复的代码提取出来,放在3个公共的地点,起个名字,今后哪个人想用那段代码,就通过那么些名字调用就行了

1.5.1 函数和进度

  在 Python 中等高校函授数和进程是分开的,函数与经过(procedure)的界别:

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

  严峻来说 Python
没有经过,只有函数,因为固然没有重返值,也会暗许重返二个 None。

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

 

 

概念: 函数是指将一组语句的集结通过三个名字(函数名)封装起来,要想进行这些函数,只需调用其函数名即可

特性:

  1. 调整和缩小重复代码
  2. 使程序变的可增添
  3. 使程序变得易维护

语法定义

def sayhi():        #函数名
    print("Hello,World!")

sayhi()        #函数调用

能够带参数

#下面这段代码
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.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
是永葆在函数内部修改全局变量的,只必要在变量后面加上2个 global
关键字即可:

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

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

  2. 内嵌函数

  函数补助嵌套,即3个函数中嵌套其它2个函数,那种函数叫内嵌函数或内部函数。

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

Tips:其间函数只可以在其间调用,外部调用会报 NameError

def test(x,y,z): #x=1,y=2,z=3
    print(x)
    print(y)
    print(z)

#位置参数,必须一一对应,缺一不行多一也不行
test(1,2,3)

#关键字参数,无须一一对应,缺一不行多一也不行
test(y=1,x=2,z=3)

#输出结果:
1
2
3
2
1
3

reduce函数:

拍卖3个队列,然后把类别进行统一操作

#  reduce函数
from functools import reduce

num = [1, 2, 3, 4, 5]
print(reduce(lambda x, y: x + y, num, ))

#输出:
15

 

2.函数参数与重回值  

形参变量唯有在被调用时才分配内部存款和储蓄器单元,在调用截至时,马上释放所分配的内部存储器单元。因而,形参只在函数内部有效。函数调用停止重临主调用函数后则不能够再利用该形参变量

实参能够是常量、变量、表明式、函数等,无论实参是何种类型的量,在进行函数调用时,它们都必须有规定的值,以便把这几个值传送给形参。因而应先行用赋值,输入等措施使参数得到明确值

函数再次来到值

#面向过程
def func1():
    "test function1"
    print("hello test 1")

#面向函数
def func2():
    "test function2"
    print("hello test 2")
    return 0

def func3():
    "test function3"
    print("hello test 3")
    return 1,"haha",[1,3],{"name":"hl","age":"26"},("a","b")    #返回函数执行结果,返回的是一个元组

x=func1()
y=func2()
z=func3()
print(x,y,z)

 

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' 已经被修改

 

停放函数:

威尼斯人线上娱乐 3

 

 

 

 

定义函数: # 语法 def
函数名(参数1,参数2,参数3,…): ”’ 注释 ”’ 函数体 return 再次回到的值 #
函数名要能反映其含义 进程:…

岗位参数和重点参数,即重点字调用

def func4(x,y):    #形参
    "argv"
    print(x)
    print(y)

func4(1,2)      #位置参数,与形参一一对应,实参
func4(y=2,x=1)  #关键参数,即关键字调用,与形参顺序无关,关键字调用必须放在位置参数之后,实参

非固定参数和暗许参数

若您的函数在概念时不显明用户想传入几个参数,就足以应用非固定参数

#*args  接收N个位置参数,转换成元组的形式
def func5(*args):
    "参数组"
    print(args)

func5(1,3,5,7)    #传入的实参是位置参数,转化成元组


#**kwargs  接收N个关键字参数,转化成字典的形式
def func6(num,count=3,**kwargs):    #count=3 是默认参数
    "参数组"
    print(num)
    print(count)
    print(kwargs)

func6(1,name="hl",age=23)    #传入实参是关键字调用,转化成字典

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.变量

1.7 递归函数

  在函数内部,能够调用别的函数,倘诺在调用进度中央直机关接或直接调用自个儿,那么那么些函数正是递归函数。

  递归函数特征:

  • 务必有令人侧指标终止条件
  • 历次进入更深一遍递归时,难点规模比上二次都应负有削减
  • 递归功能不高,层次过多容易导致 栈溢出

函数调用是经过栈达成,每调用一回,栈就会追加一层栈帧,函数再次回到,则缩减一层。由于栈的轻重有限,全体递归过多,就会导致栈溢出。

def func:    print    if int == 0:       # 结束条件        return n    res = func   # 调用自身    return resfunc10,5,2,1
#参数组:**字典 *列表
def test(x,*args,**kwargs):
    print(x)
    print(args,args[-1])
    print(kwargs,kwargs.get('s'))
test(1,*[1,2,3],**{'s':1})

#输出结果:
1
(1, 2, 3) 3
{'s': 1} 1

一些变量和全局变量

在子程序中定义的变量称为局地变量,在程序的一上马定义的变量称为全局变量。

全局变量功效域是全方位程序,局地变量功能域是概念该变量的子程序。

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

在概念局地变量的子程序内,局地变量起效果;在其余地点全局变量起成效。

age = 26
name = "hl"
list_1 = ["alex","oldboy"]
def change_name(age,name):
    print("before change:", age, name, list_1)
    age = 18
    name = "HL"
    list_1[0] = "Alex"
    print("after change:",age , name, list_1)

change_name(age,name)
print("globe",name)
print("globe",age)
print("globe",list_1)

#字符串,整数,局地变量的改动不会潜移默化全局变量
#列表,字典,集合,局地变量的修改会影响全局变量

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]要找的数字不在列表中

 

4. 递归

在函数内部,能够调用别的函数。假使三个函数在个中调用自家自身,这几个函数就是递归函数。

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

calc(10)

递归天性:

  1. 不可能不有二个引人侧目的结束条件

  2. 老是进入更深一层递归时,难题规模比较上次递归都应负有削减

3.
递归功能不高,递归层次过多会导致栈溢出(在电脑中,函数调用是经过栈(stack)这种数据结构达成的,每当进入三个函数调用,栈就会加一层栈帧,每当函数再次回到,栈就会减一层栈帧。由于栈的大小不是无与伦比的,所以,递归调用的次数过多,会造成栈溢出)

 

递归函数实际应用案例,二分查找

威尼斯人线上娱乐 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("\033[31;1m找的数在mid[%s]左面\033[0m" % dataset[mid])
            return binary_search(dataset[0:mid], find_num)
        else:# 找的数在mid右面
            print("\033[32;1m找的数在mid[%s]右面\033[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)

View Code

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,在内部存储器中形成3个调用记录,又叫做调用帧(call
frame)。用于存款和储蓄调用地方和中间变量等音讯,即,直至 c 重回结果给 b,c
的调用记录消失。b 重临给 a,b 的调用记录消失,a 再次回到结果,a
的调用记录消失,全部记录都是先进后出,形成一个调用栈(call stack)

全局变量和一些变量:

在子程序中定义的变量称为局部变量,在先后的一从头定义的变量称为全局变量。

全局变量功效域是成套程序,局地变量功能域是概念该变量的子程序。

当全局变量与部分变量同名时:在概念局地变量的子程序内,局地变量起功用;在其余地点全局变量起功效。

 

name='reese'
def change_name():
    print('我的名字',name)
change_name()


def change_name():
    name='帅'
    print('我的名字',name)
change_name()
print(name)


def change_name():
    global name
    name='帅'
    print('我的名字',name)
change_name()
print(name)

#输出结果:
我的名字 reese
我的名字 帅
reese
我的名字 帅
帅

 #
如若函数内部无global关键字,优先读取局地变量,能读取全局变量,不可能对全局变量重新赋值;

   
但对于可变类型(除数字、字符串、元祖,别的都可变),可对中间因素举行操作。

#
若是函数内部有global关键字,变量本质上是全局变量,可读取可赋值。

#
一般全局变量名用大写,局地变量名用小写。

 

5. 匿名函数

匿名函数正是不须求显式的钦赐函数

 

 

1.8 匿名函数

  匿名函数即不须要彰显地钦点函数名的函数,Python 允许利用 lambda
关键字来创立三个匿名函数,匿名函数也被喻为 lambda 表明式。

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

  冒号右侧是原函数参数,能够有多少个参数,逗号分隔即可,冒号左边为重返值。对于有个别结构相比较不难的函数,可以一向定义为匿名函数:

def func:    return x+2s = funcprint

  上述函数可从来定义1个匿名函数:

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 表明式的遵守:

  • 实施一些剧本时,省略定义函数进度
  • 对此全部程序只须要执行一三回的函数,不用考虑命名难题
  • 简化代码步骤

 

2. 函数式编制程序

递归 

#递归调用

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


calc(10)

#输出:
10
5
2
1

 

递归性情:

  1. 无法不有二个显眼的了断条件

2.
老是进入更深一层递归时,难点规模比较上次递归都应拥有减小

  1. 递归功能不高,递归层次过多会导致栈溢出(在电脑中,函数调用是经过栈(stack)这种数据结构完毕的,

每当进入三个函数调用,栈就会加一层栈帧,每当函数再次回到,栈就会减一层栈帧。由于栈的轻重不是无与伦比的,所以,递归调用的次数过多,会招致栈溢出)

 

#问路

import time

person_list=['林克','士官长','奎爷','但丁']
def ask_way(person_list):
    print('-'*60)
    if len(person_list) == 0:
        return '没人知道'
    person=person_list.pop(0)
    if person == '但丁':
        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)

 

2.1 编程论

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

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

  函数式编制程序,更接近数学,是一种浮泛圣Juan很高的编制程序范式,不容许函数有变量。但
Python 不是从严意义上的函数式编制程序,因为它同意有变量。

  函数式编程特点:

  • 函数即变量(1个函数作为参数字传送入另五个函数)
  • 重临值是函数(能够函数本人,也得以是别的函数)

  函数即变量

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()

函数效能域

 

作用域在概念函数时就早已固化住了,不会趁机调用地方的更动而变更

name = "reese"
def s():
    name = "neo"
    def n():
        print(name)
    return n

func = s()
func()

#输出:
neo

 

2.2 高阶函数

  函数式编程的七个性格:函数即变量,重回值是函数,只需满足在那之中多个标准,即可成为高阶函数。

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

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

 

2.2.1 map 函数

  map(function, sequence)
函数是高阶函数的一种,它有多少个参数:第②个为函数,另3个接收四个种类。

  其职能是将种类中种种成分,作为函数参数字传送入第3个参数中,直至连串中各样成分都被循环,回去贰个迭代器对象,用
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)

匿名函数:

不须要显示的钦定函数

def calc(x):
    return x + 10


res = calc(10)
print(res)

#输出:
20


#用匿名函数:
func = lambda x: x + 10
print(func(10))

#输出:
20

 

func = lambda x, y, z: x + y + z
print(func(1, 2, 3))

#输出:
6

 

 

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]

 

2.2.3 reduce 函数

  reduce(function, sequence[, initial])函数两个参数:第四个为函数,第①个为类别,第一个可选为起头值。

  Python3 把 reduce 函数集成到 functools
模块中,因而老是使用时,需求from functools import reduce。它能够把2个函数成效在三个行列上,那个函数必须接受三个参数。首先将类别中的前五个要素取出,传入函数中,重临值再与体系中接下去的因素做累积计算,直至连串中的每种成分都被循环。

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

  常规:

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 前多少个要素,即 壹 、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

map函数:

 

num = [3, 4, 5, 6, 11, 7, 54]
#lambda x:x+1
def add_one(x):   #列表元素自增一
    return x + 1

#lambda x:x-1
def minus_one(x):  #列表元素自减一
    return x - 1


def map_test(func, array):
    ret = []
    for i in num:
        res = func(i)
        ret.append(res)
    return ret
print(map_test(add_one,num))
# print(map_test(lambda x:x+1,num)) #可用匿名函数
print(map_test(minus_one,num))
# print(map_test(lambda x:x-1,num))


#终极版本
def map_test(func,array):
    ret = []
    for i in array:
        res = func(i)
        ret.append(res)
    return ret

print(map_test(lambda x:x+1,num))

#输出结果:
[4, 5, 6, 7, 12, 8, 55]
[2, 3, 4, 5, 10, 6, 53]
[4, 5, 6, 7, 12, 8, 55]

 

 map:

拍卖系列中的每种成分,得到的结果是多个列表,该列表成分个数及岗位与原先一样

num = [3, 4, 5, 6, 11, 7, 54]
res=map(lambda x:x+1,num)
print('内置函数map,处理结果',list(res))

print(list(map(minus_one,num)))

msg = "reese"
print(list(map(lambda x:x.upper(),msg)))

#输出结果:
内置函数map,处理结果 [4, 5, 6, 7, 12, 8, 55]
[2, 3, 4, 5, 10, 6, 53]
['R', 'E', 'E', 'S', 'E']

 

2.2.4 sorted 函数

  排序算法在程序中是日常使用的算法,无论是冒泡还是快排,其宗旨都是相比较多个成分的轻重缓急。

  • 数字:从来相比较
  • 字符串/字典:急需用函数抽象出来相比

  sorted(iterable, key, reverse)函数也是1个高阶函数,在列表内置方法中大家就曾经接触到了,它能够对四个列表举办排序,暗许从小到大。

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

  别的,它还吸收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']

filter函数:

方便体系中的每个成分,判断每种成分获得布尔值,借使是True则留下来

people = ['reese', 'neo_s', '林克']
print(filter(lambda n: not n.endswith('s'), people))

res = filter(lambda n: not n.endswith('s'), people)
print(list(res))

print(list(filter(lambda n: not n.endswith('s'), people)))

#输出:
<filter object at 0x04E612B0>
['reese', '林克']
['reese', '林克']

 

 

2.2.5 偏函数

  functools 模块提供了累累效应,个中一个正是偏函数。

  当函数的参数个数太多,须求简化时,使用 functools.partial
创建贰个偏函数,那些新的函数能够一定住原函数的局地参数,从而调用更简约。

语法结构:

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

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

  int() 函数可以把字符串转换为整型,默许根据十进制转换:

>>> int('123')123

  int() 函数还附加提供八个 base 参数,假设传入 base,就能够做 N
进制转换:

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

松开函数

  假如要转换大批量的二进制字符串,每趟都要传播
base,就会很麻烦。大家能够动用偏函数将 base=2
固定住,定义1个新的函数,每便只必要传入要转换的字符串即可:

>>> 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}]

reduce函数:

处理贰个行列,然后把类别实行统一操作

#  reduce函数
from functools import reduce

num = [1, 2, 3, 4, 5]
print(reduce(lambda x, y: x + y, num, ))

#输出:
15

 

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'\xe4\xbd\xa0\xe5\xa5\xbd'>>> 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)有五个参数:第3个是待鲜明项指标数量,首个是钦赐叁个数据类型,判断双方是或不是一律,重临贰个布尔值。

>>> 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()再次来到3个体系中的最大、小成分。

  特性:

  • 原理是将类别中各种元素都循环遍历出来相比
  • 率先比较第3个字符,分出大小则甘休相比,若分出,钻继续比较。不相同数据类型不能够相比较
  • 字典相比,私下认可相比 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}

放到函数:

威尼斯人线上娱乐 6

 

 

 

 


相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图