递归、匿名函数、内置函数

递归

 递归调用是函数嵌套调用的一种特殊形式。函数在调用的时候,直接或者间接的调用了自身。

比如:

#直接调用本身
def f1():
    print('from f1')
    f1()
f1()

#间接调用本身
def f1():
    print('from f1')
    f2()

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

# 调用函数会产生局部的名称空间,占用内存,因为上述这种调用会无需调用本身,python解释器的内存管理机制为了防止其无限制占用内存,对函数的递归调用做了最大的层级限制
四 可以修改递归最大深度

import sys
sys.getrecursionlimit()
sys.setrecursionlimit(2000)

def f1(n):
    print('from f1',n)
    f1(n+1)
f1(1)

虽然可以设置,但是因为不是尾递归,仍然要保存栈,内存大小一定,不可能无限递归,而且无限制地递归调用本身是毫无意义的,递归应该分为两个明确的阶段,回溯与递推
View Code

递归调用应该分为两个明确的阶段:递推和回溯

#1、递归调用应该包含两个明确的阶段:回溯,递推
    回溯就是从外向里一层一层递归调用下去,
        回溯阶段必须要有一个明确地结束条件,每进入下一次递归时,问题的规模都应该有所减少(否则,单纯地重复调用自身是毫无意义的)

    递推就是从里向外一层一层结束递归

#2、示例+图解。。。
# salary(5)=salary(4)+300
# salary(4)=salary(3)+300
# salary(3)=salary(2)+300
# salary(2)=salary(1)+300
# salary(1)=100
#
# salary(n)=salary(n-1)+300     n>1
# salary(1) =100                n=1

def salary(n):
    if n == 1:
        return 100
    return salary(n-1)+300

print(salary(5)) 
View Code

递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

补充:二分法

想从一个按照从小到大排列的数字列表中找到指定的数字,遍历的效率太低,用二分法(算法的一种,算法是解决问题的方法)可以极大低缩小问题规模

l=[1,2,10,30,33,99,101,200,301,311,402,403,500,900,1000] #从小到大排列的数字列表

def search(n,l):
    print(l)
    if len(l) == 0:
        print('not exists')
        return
    mid_index=len(l) // 2
    if n > l[mid_index]:
        #in the right
        l=l[mid_index+1:]
        search(n,l)
    elif n < l[mid_index]:
        #in the left
        l=l[:mid_index]
        search(n,l)
    else:
        print('find it')


search(3,l)

# 优化后——————————————————————
l=[1,2,10,30,33,99,101,200,301,402]

def search(num,l,start=0,stop=len(l)-1):
    if start <= stop:
        mid=start+(stop-start)//2
        print('start:[%s] stop:[%s] mid:[%s] mid_val:[%s]' %(start,stop,mid,l[mid]))
        if num > l[mid]:
            start=mid+1
        elif num < l[mid]:
            stop=mid-1
        else:
            print('find it',mid)
            return
        search(num,l,start,stop)
    else: #如果stop > start则意味着列表实际上已经全部切完,即切为空
        print('not exists')
        return

search(301,l)
View Code

匿名函数

匿名函数就是没有名字

比如:

lambda x,y,z=1:x+y+z

匿名函数和普通函数有相同的作用域。而且没有return,结构较为简单,只能放一个执行语句。

匿名意味着引用计数为0,使用就释放了,除非有名字指向它。

比如:

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

匿名函数常用于内置函数:max,min,sorted,map,reduce,filter

内置函数

#注意:内置函数id()可以返回一个对象的身份,返回值为整数。这个整数通常对应与该对象在内存中的位置,但这与python的具体实现有关,
不应该作为对身份的定义,即不够精准,最精准的还是以内存地址为准。is运算符用于比较两个对象的身份,等号比较两个对象的值,
内置函数type()则返回一个对象的类型
#更多内置函数:https://docs.python.org/3/library/functions.html?highlight=built#ascii

map函数

格式:

map(参数1,参数2)

map中第一个参数是函数,第二个参数是一个可迭代对象。这个可迭代对象会逐个带入到函数中进行处理。返回的结果是一个map对象。

注意:如果是再python2中,返回的就是一个列表对象

比如:

s = "中华人民共和国"
print(map(lambda x:x.upper(), s))
print(type(map(lambda x:x.upper(), s)))     # <class 'map'>
print(list(map(lambda x:x.upper(), s)))     # ['中', '华', '人', '民', '共', '和', '国']
# 例子中我将其转为一个列表显示。
View Code

filter函数

和map函数格式一致,只不过第一个参数的结果转换为布尔值,将布尔值为真的挑选出来,返回的是一个filter对象

比如:

a = [13, 342, 4532, 51, 1, 3, 6]
res = filter(lambda n: not n < 20, a)
print(type(res))    # <class 'filter'>
print(list(res))    # [342, 4532, 51]
View Code

reduce函数

格式:

from functools import reduce
reduce(参数1,参数2,参数3)

参数2为可迭代对象,将参数2带入到参数1中进行运算,如果有额外元素的话,运算的话可以加入参数3

比如:

from functools import reduce
num_l = ["11", "22", "33"]  
print(reduce(lambda x, y: x+y, num_l, "**"))        # **112233
print(reduce(lambda x, y: x+y, num_l))              # 112233

--------------------------------------------------------------
from functools import reduce
num_l=[1, 2, 3, 100]
print(reduce(lambda x, y: x+y, num_l, 1))   # 107
print(reduce(lambda x, y: x+y, num_l))      # 106
View Code

zip函数

格式:

zip(参数1,参数2)

参数必须是序列类型(列表,元组,字符串),zip函数会将两个参数一一对应放在一个元组中,返回的是一个zip对象

比如:

res = zip(("a", "n", "c"), (1, 2, 3))
print(type(res))    # <class 'zip'>
print(list(res))    # [('a', 1), ('n', 2), ('c', 3)]

p = {"张三": 20,
     "李四": 30,
     "王五": 40,
     }
print(list(zip(p.values(), p.keys())))      # [(20, '张三'), (30, '李四'), (40, '王五')]
View Code

max、min函数

max函数和min函数处理数据的时候,相当于处理可迭代对象,相当于用for循环取出每一个元素进行比较。需要注意的是:不同类型不能进行比较。比较字符串的时候,是先比较第一位,如果相同再继续比较,最后得出结果。

max函数和min函数如果要处理其他的数据比较很简单,但是要比较字典的话,可以用上面说到的zip函数将字典改变成value在前,key在后的形式,然后强转成字典,用max函数和min函数比较。这两个函数在比较字典的时候是比较字典的key的,所有可以利用这个特性。

max函数和min函数中,还有可以指定一个方法,用key关键字传递给max进行处理

比如:

p = {"张三": 20,
     "李四": 30,
     "王五": 40,
     }
res = dict(zip(p.values(), p.keys()))
print(res)      # {40: '王五', 20: '张三', 30: '李四'}
print(max(res))     # 40
View Code

还有一种形式就是将容器中的字典内容进行比较:

比如:

p = [
    {"name": "张三", "age": 20},
    {"name": "赵四", "age": 30},
    {"name": "王五", "age": 40},
    {"name": "钱六", "age": 50}
]
print(max(p, key=lambda dic: dic['age']))       # {'age': 50, 'name': '钱六'}
View Code

slice函数

slice函数可以定义切片的设置,然后传给切片。

l = "中华人民共和国"
s1 = slice(3, 5, 2)
print(l[s1])        #
print(s1.start)     # 3
print(s1.stop)      # 5
print(s1.step)      # 2
View Code

eval函数

eval函数有两个功能,第一个是:将字符串中的数据结构提取出来。第二个是:将字符串中的表达式计算

例如:

res = eval("[1, 3, 4,]")
print(res)          # [1, 3, 4]
print(eval("2*3*3"))        # 18
View Code

format函数

#字符串可以提供的参数 's' None
>>> format('some string','s')
'some string'
>>> format('some string')
'some string'

#整形数值可以提供的参数有 'b' 'c' 'd' 'o' 'x' 'X' 'n' None
>>> format(3,'b') #转换成二进制
'11'
>>> format(97,'c') #转换unicode成字符
'a'
>>> format(11,'d') #转换成10进制
'11'
>>> format(11,'o') #转换成8进制
'13'
>>> format(11,'x') #转换成16进制 小写字母表示
'b'
>>> format(11,'X') #转换成16进制 大写字母表示
'B'
>>> format(11,'n') #和d一样
'11'
>>> format(11) #默认和d一样
'11'

#浮点数可以提供的参数有 'e' 'E' 'f' 'F' 'g' 'G' 'n' '%' None
>>> format(314159267,'e') #科学计数法,默认保留6位小数
'3.141593e+08'
>>> format(314159267,'0.2e') #科学计数法,指定保留2位小数
'3.14e+08'
>>> format(314159267,'0.2E') #科学计数法,指定保留2位小数,采用大写E表示
'3.14E+08'
>>> format(314159267,'f') #小数点计数法,默认保留6位小数
'314159267.000000'
>>> format(3.14159267000,'f') #小数点计数法,默认保留6位小数
'3.141593'
>>> format(3.14159267000,'0.8f') #小数点计数法,指定保留8位小数
'3.14159267'
>>> format(3.14159267000,'0.10f') #小数点计数法,指定保留10位小数
'3.1415926700'
>>> format(3.14e+1000000,'F')  #小数点计数法,无穷大转换成大小字母
'INF'

#g的格式化比较特殊,假设p为格式中指定的保留小数位数,先尝试采用科学计数法格式化,得到幂指数exp,如果-4<=exp<p,则采用小数计数法,并保留p-1-exp位小数,否则按小数计数法计数,并按p-1保留小数位数
>>> format(0.00003141566,'.1g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留0位小数点
'3e-05'
>>> format(0.00003141566,'.2g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留1位小数点
'3.1e-05'
>>> format(0.00003141566,'.3g') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留2位小数点
'3.14e-05'
>>> format(0.00003141566,'.3G') #p=1,exp=-5 ==》 -4<=exp<p不成立,按科学计数法计数,保留0位小数点,E使用大写
'3.14E-05'
>>> format(3.1415926777,'.1g') #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留0位小数点
'3'
>>> format(3.1415926777,'.2g') #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留1位小数点
'3.1'
>>> format(3.1415926777,'.3g') #p=1,exp=0 ==》 -4<=exp<p成立,按小数计数法计数,保留2位小数点
'3.14'
>>> format(0.00003141566,'.1n') #和g相同
'3e-05'
>>> format(0.00003141566,'.3n') #和g相同
'3.14e-05'
>>> format(0.00003141566) #和g相同
'3.141566e-05'
View Code

exec函数

# exec:三个参数

# 参数一:包含一系列python代码的字符串

# 参数二:全局作用域(字典形式),如果不指定,默认为globals()

# 参数三:局部作用域(字典形式),如果不指定,默认为locals()

# 可以把exec命令的执行当成是一个函数的执行,会将执行期间产生的名字存放于局部名称空间中
g = {
    'x': 1,
    'y': 2
}
l = {}

exec('''
global x,z
x=100
z=200

m=300
''', g, l)

print(g)  # {'x': 100, 'y': 2,'z':200,......}
print(l)  # {'m': 300}

# 说明:即使是在三引号中也要注意缩进问题。
View Code

 

其他内置函数

abs():求绝对值

all():只能给一个参数,里面参数都为真(类似列表的,是列表中的每个元素,真则要注意哪些情况下布尔值为真),返回True,否则返回False,

bytes(参数,encoding="utf-8"):将参数转为指定的编码格式。

chr():将整数转成对应的字符

ord():将字符转成对应的整数

dir():将参数的方法显示出来。

divmod(被除数,除数):返回的是一个元组,元组的第一个为商,第二个为余数

hash():将参数生成一个hash值,这个hash值是固定长度的,而且内容改变hash也改变。可以用来校验是否有人修改文件内容。补充:可以hash的数据类型即不可变数据类型,不可hash的数据类型即可变数据类型。

help():参数是方法名,用来查看方法如何使用。

bin():十进制转二进制。0b开头

hex():十进制转十六进制。0x开头

oct():十进制转八进制。0o开头

isinstance(参数一,参数二):判断参数一是不是参数二的实例。比如:isinstance(1,int)

globals():显示系统所有的全局变量

locals():显示本模块内局部变量

pow(参数一,参数二,参数三):参数一的参数二次方,参数三可加可不加,加了表示对前两个计算出来的结果取余

reversed():对参数进行反转

round():四舍五入

sorted():排序,不同类型不可以排序,和max原理是一样的,也可以指定一个方法,然后用key传给sorted,默认是升序

sum() :求和

type():返回类型。

__import__():将模块名的字符串形式放入参数中。会导入这个模块

比如:

m = __import__("demo")

m.say_hello()
View Code

其他内置参数可见:https://docs.python.org/3/library/functions.html?highlight=built#ascii

 

posted @ 2018-05-21 15:33  苦行僧95  阅读(238)  评论(0编辑  收藏  举报