Python内置函数二 (递归函数,匿名函数,二分法)

匿名函数

lambda()

语法: lambad  参数 : 返回值

1 def func(a,b):
2     return a * b
3 print(func(2,5))
4 
5 a = lambda a ,b : a*b # 将上面的函数用一行代码完成
6 print(a(2,5))

所有匿名函数的名字都是  lambda   可以赋值其他变量名 ,可以自己认为其他变量名是 函数名 

查看函数名:

上面函数名查看


print(func.__name__)
print(a.__name__)


#用来查看函数名

func
<lambda>

lambda函数可以返回多个值

a = lambda a,b : (a,b)
print(a(2,3))

结果
(2, 3)


返回多个值接收,必须要用元组
返回的是元组

 

sorted()       排序函数

语法: sorted(iterable,key, reverse)

key  排序规则

运行流程:   把可迭代对象中的每一个元素交给后面key函数来执行,得到一个数字(权重),通过这个数字进行排序 

 1 lis = [1,34,3,5,2,6,8,32,45,65,76]
 2 a = sorted(lis)  # 内置函数提供了一个通用的排序方案  ,sorted()
 3 print(a)
 4 
 5 结果
 6 [1, 2, 3, 5, 6, 8, 32, 34, 45, 65, 76]
 7 
 8 lis1 = ["江南","一个人","牧马人","风筝误","不仅仅是喜欢","","醉千年","你要的全拿走",]
 9 a = sorted(lis1,key= lambda el:len(el))   #  根据字符串的长度进行排序   key 用于列表的取值条件
10 print(a)
11 
12 结果
13 ['', '江南', '一个人', '牧马人', '风筝误', '醉千年', '不仅仅是喜欢', '你要的全拿走']
14 
15 lis1 = ["江南","一个人","牧马人","风筝误","不仅仅是喜欢","","醉千年","你要的全拿走",]
16 a = sorted(lis1, key = lambda el :len(el),reverse = True # 倒序排列
17 print(a)
18 
19 结果
20 ['不仅仅是喜欢', '你要的全拿走', '一个人', '牧马人', '风筝误', '醉千年', '江南', '']

 

filter() 函数        过滤函数

语法 : filter(function,iterable)

运行流程:  把可迭代的对象中的每一个元素交给其前面的函数进行筛选, 函数返回的是Ture 或者  False

1 lis = ["张三丰","张无忌","张青","梦三","刘龙","黄屁孩","找语句","汪峰","你没"]
2 a = filter(lambda el : el[0]!="",lis)  #  过滤掉姓张的
3 print(a)  # 打印的是内存地址  同时也是一个可迭代的对象
4 print(list(a))   
5 
6 结果
7 <filter object at 0x000002988F147940>
8 ['梦三', '刘龙', '黄屁孩', '找语句', '汪峰', '你没']

 

map()  函数     映射函数

语法 :map(function,iterable)

运行流程:   把可迭代对象中的数据交给前面的函数进行执行   返回值就是map()的处理结果

1 计算列表的平方
2 lis = [2,3,45,6,7,8,9,10]
3 a = map(lambda i : i**2,lis)
4 print(a)  #   返回的是内存地址   只一个可迭代的对象
5 print(list(a))
6 
7 结果
8 <map object at 0x00000238110F7860>
9 [4, 9, 2025, 36, 49, 64, 81, 100]

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

语法 :   reduce()函数接收的参数和 map()类似,一个函数 f,一个list,但行为和 map()不同,reduce()传入的函数 f 必须接收两个参数,reduce()对list的每个元素反复调用函数f,并返回最终结果值。

 

例如,编写一个f函数,接收x和y,返回x和y的和:

def f(x, y):
    return x + y

调用 reduce(f, [1, 3, 5, 7, 9])时,reduce函数将做如下计算:

先计算头两个元素:f(1, 3),结果为4;
再把结果和第3个元素计算:f(4, 5),结果为9;
再把结果和第4个元素计算:f(9, 7),结果为16;
再把结果和第5个元素计算:f(16, 9),结果为25;
由于没有更多的元素了,计算结束,返回结果25。

上述计算实际上是对 list 的所有元素求和。虽然Python内置了求和函数sum(),但是,利用reduce()求和也很简单。

reduce()还可以接收第3个可选参数,作为计算的初始值。如果把初始值设为100,计算:

reduce(f, [1, 3, 5, 7, 9], 100)

结果将变为125,因为第一轮计算是:

计算初始值和第一个元素:f(100, 1),结果为101

 

重要特点:分而治之    批量处理数据

语法:map(func1,map(func2,map(func3,map(func4,lis))

1 也具有水桶效应   与zip()相似
2 
3 lis1 = [1,2,3,4,5,6]
4 lis2 = [12,23,34,45,56,67]
5 a = map(lambda a,b:a+b,lis1,lis2)  # 可以接多个对象, 同时要对应对个参数  同时也根据最短列表对应的长度计算
6 print(list(a))
7 
8 [13, 25, 37, 49, 61, 73]

 

递归函数     自己调用自己

例如:

1 count = 1
2 def func():
3     global count
4     print("我要学习,拿高薪15K",count)
5     count += 1
6     func()
7 
8 func()

 

递归深度:   就是自己调用自己的次数

官方文档中说 递归的最大深度是1000, 在这之前就会给你报错

一般执行到998左右就会停止,程序报错

 

递归简单用途 :  病毒软件    杀毒软件

文件操作:

 1 import os
 2 def func(lujing,n):  # 方便查看文件夹分级
 3     filts = os.listdir(lujing)  #打开文件
 4     for filt in filts:   #查看文件名
 5         filt_lj = os.path.join(lujing,filt)   # 拼接成一个文件路径
 6         if os.path.isdir(filt_lj):   # 判断是否为文件夹
 7             print("\t"*n,filt)  #  打印文件夹分级
 8             func(filt_lj,n+1)
 9         else:
10             print("\t"*n,filt)   #  打印文件夹分级
11 
12 func("f:\Python讲义视频",0)

 

原版
import os
def read(filepath, n):
 files = os.listdir(filepath) # 获取到当前⽂件夹中的所有⽂件
 for fi in files: # 遍历⽂件夹中的⽂件, 这⾥获取的只是本层⽂件名
 fi_d = os.path.join(filepath,fi) # 加⼊⽂件夹 获取到⽂件夹+⽂件
 if os.path.isdir(fi_d): # 如果该路径下的⽂件是⽂件夹
 print("\t"*n, fi)
 read(fi_d, n+1) # 继续进⾏相同的操作
 else:
 print("\t"*n, fi) # 递归出⼝. 最终在这⾥隐含着return
#递归遍历⽬录下所有⽂件
read('../oldboy/', 0)

 

二分查找法

使用二分查找法可以提高效率,前提条件必须有序

例如

      函数二分法

 

 1 lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789]
 2 def func(n, left, right):
 3     if left <= right: # 边界
 4         mid = (left + right)//2
 5         if n > lst[mid]:
 6             left = mid + 1
 7             return func(n, left, right) # 递归  递归的入口
 8         elif n < lst[mid]:
 9             right = mid - 1
10             # 深坑. 函数的返回值返回给调用者
11             return func(n, left, right)    # 递归
12         elif n == lst[mid]:
13             print("找到了")
14             return mid
15             # return  # 通过return返回. 终止递归
16     else:
17         print("没有这个数") # 递归的出口
18         return -1 # 1, 索引+ 2, 什么都不返回, None
19 # 找66, 左边界:0,  右边界是:len(lst) - 1
20 ret = func(70, 0, len(lst) - 1)
21 print(ret) # 不是None

 

 

 

 while循环二分法

 1 l = 0
 2 r = len(lis)-1
 3 n = 5
 4 while l < r:
 5     mid = (r +l)//2
 6     if n > lis[mid]:
 7         l = mid +1
 8     if n < lis[mid]:
 9         r = mid -1
10     if n == lis[mid]:
11         print("存在")
12         break
13 else:
14     print("不存在")

 

另类二分法  切片

def binary_search(ls, target):
 left = 0
 right = len(ls) - 1
 if left > right:
 print("不在这⾥")
 middle = (left + right) // 2
 if target < ls[middle]:
 return binary_search(ls[:middle], target)
 elif target > ls[middle]:
 return binary_search(ls[middle+1:], target)
 else:
 print("在这⾥")
binary_search(lst, 567)

 

最快查找

用列表查找

lis1=[1,5,9,6,85,12]
lis2 将列表中的lis1中最大数表示列表长度,列表2用 0  1 表示,,  有数的表示1  没有的表示0

1 时间复杂度最低, 空间复杂度最低
2 lst1 = [5, 6, 7, 8]
3 lst2 = [0, 0, 0, 0, 0, 1, 1, 1, 1]
4 for el in lst1:
5     lst2[el] = 1
6 
7 lst2[4] == 1  # o(1)

 

posted @ 2018-08-15 20:08  heshun  阅读(248)  评论(0编辑  收藏  举报