匿存函数,内存函数,递归函数,二分法查找

∥☆過路亽.° 提交于 2020-02-05 21:01:22

一.匿名函数(lambda)

语法:  lambda  参数: 返回值

函数名统一都叫lambda

1.把普通函数转换成匿名函数

def func(n)
    return n * n
ret = func(9)
print(ret)
普通
a = lambda n: n * n
ret = a(9)
print(ret)
匿名

其中a可以认为是函数名,但是在__name__中函数名统一是lambda

print(func.__name__)  #查看函数名
print(a.__name__)       #__name__的值都是<lambda>
查看函数名
def func(a, b)
    return a + b

x = lambda a, b : a+b
print(x(a , b))
两个参数的匿名函数
def func(x, y)
    return x, y

s = lambda x, y :(x, y)#如果不放(),s会被分为两部分 lambda x, y :x和y
print(s(250, 38))
两个返回值的匿名函数
fn = lambda *args :max(args) #匿名函数一定是一行函数
print(fn(1,3,8,56))#56
求最大值

二.sorted()  排序函数

语法:sorted(iterable, key, reverse)

key:排序规则.

运行流程: 把可迭代的对象中是每一个元素交给后面的key函数来执行.

    得到一个数字(权重).通过这个数字进行排序

lst = ["聊斋", "西游记", "三国演义", "葫芦娃", "水浒传", "年轮", "亮剑"]
def func(s)
    return len(s)
li = sorted(lst, key = func)
print(li)
#key: 排序方案, sorted函数内部会把可迭代对象中的每一个元素拿出来交给#后面的key,后面的key计算出一个数字. 作为当前这个元素的权重, 整个函根
#据权重进行排序
根据字数排列
lst = [
    {'name':"汪峰","age":48},
    {"name":"章子怡",'age':38},
    {"name":"alex","age":39},
    {"name":"wusir","age":32},
    {"name":"赵一宁","age":28}
    ]

ll = sorted(lst, key=lambda el: len(el['name']), reverse=True)
print(ll)
View Code

三.filter() 过滤函数

语法:     filter(function, iterable)

运行流程;把可迭代对象中的数据交给前面的函数进行筛选.函数返回True或者False

#普通函数
lst = ["张无忌", "张铁林", "赵一宁", "石可心","马大帅"]
def func(el)
    if el[0] == "张"
        return False  #不想要的
    else:
        return True  #想要的
f = filter(func, lst)
print("__iter__" in dir(f)) # 判断是否可以进行迭代
for e in f:
     print(e)

#匿名函数
f = filter(lambda el :el[0] != "张", lst)
print("__iter__" in dir(f)) # 判断是否可以进行迭代
for e in f:
     print(e)
排除姓张的人
 lst = [
     {"name":"汪峰", "score":48},
     {"name":"章子怡", "score":39},
     {"name":"赵一宁","score":97},
     {"name":"石可心","score":90}
 ]

 f = filter(lambda el: el['score'] < 60 , lst) # 去16期的人

 print(list(f))
求分数小于60的

四.map()     映射函数

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

lst = [1,4,7,2,5,8]
li = []
#第一种方法:算法
for el in lst:
    li.append(el**2)
#第二种方法:普通函数
def func(el)
    return el**2
m = map(func, lst)
print(list(m))
#第三种方法:匿名函数
m = map(lambda el: el**2, lst)
print(list(m))
# 把后面的可迭代对象中的每一个元素传递给function, 结果就是function返
#回值
计算列表中每个数字的平方
map(func1, map(func2, map(func3 , lst)))
分而治之
map(func1, map(func2, map(func3 , lst)))当我们处理的数据过大时可以用分而治之的思想(如人工智能中的数据处理)

五.递归函数(默认递归函数是死循环)

1.定义:函数自己调用自己

2.递归函数的深度: 1000. 到不了1000就会停止(深度可以自己设置)

import sys
sys.setrecursionlimit()
深度
count = 1
def func():
    global count
    print("alex是很帅的", count)
    count = count + 1
    func()
func() 递归深度. 你可以自己掉用自己的次数,官方文档中递归最大深度是1000. 在这之前就会给你报错

3.递归函数的用处

3.1处理相似的操作

# 遍历 D:/sylar文件夹, 打印出所有的文件和普通文件的文件名
import os
def func(filepath, n): # d:/sylar/
     # 1,打开这个文件夹
     files = os.listdir(filepath)
     # 2. 拿到每一个文件名
     for file in files:  # 文件名
         # 3. 获取到路径
        f_d = os.path.join(filepath, file) # d:/sylar/文件名/
         # 4. 判断是否是文件夹
        if os.path.isdir(f_d):
             # 5. 如果是文件夹. 继续再来一遍
             print("\t"*n, file,":") # 打印文件名
             func(f_d, n + 1)
        else:   #  不是文件夹. 普通文件
            print("\t"*n, file)

 func("d:/sylar",0)
遍历文件

3.2传播病毒(要在每个文件夹下的每个文件投放病毒)

3.3杀毒

3.4求阶乘

def func(n,s):    #计算n的阶乘
    if n > 0:
        s = n * s
        n = n - 1
        return func(n,s)
    else:
        return s
ret = func(8,1)
print(ret)
阶乘

3.5斐波那契(如计算第400个数,  不超过4000000(400万)最多计算几次)

def func(n,i,a,b):#a第一个数,b第二个数,i是第几次计算
    c = a + b # 第三个数
    if n > i:
        a = b
        b = c
        i+=1
        return func(n,i,a,b )
    else:
        return c
ret = func(400,3,1,1)
print(ret)
View Code
def func(n,i,a,b):#a第一个数,b第二个数,i是第几次计算
    c = a + b # 第三个数
    if n > c:
        a = b
        b = c
        i+=1
        return func(n,i,a,b )
    else:
        return i
ret = func(4000000,3,1,1)
print(ret)
计算几次

4.递归函数中的return 返回值,返回给上一层调用者

六.二分法

1.二分法的核心: 掐头去尾取中间,一次砍一半

2.两种算法:常规循环,递归循环

 lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789 ]
n = 79

for el in lst:
     if el == n: # O(1)
        print("找到了")
        break
else:
    print("没有")
View Code
使用二分法可以提高效率, 前提条件:有序序列
lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789]
n = 88
left = 0
right = len(lst)-1
while left <= right: # 边界, 当右边比左边还小的时候退出循环
    mid = (left + right)//2 # 必须是整除. 因为索引没有小数
    if lst[mid] > n:
        right = mid - 1
    if lst[mid] < n:
        left = mid + 1
    if lst[mid] == n:
        print("找到了这个数")
        break
else:
     print("没有这个数")
二分法查找
lst = [22, 33, 44, 55, 66, 77, 88, 99, 101 , 238 , 345 , 456 , 567 , 678 , 789]
def func(n, left, right):
    if left <= right: # 边界
        print("哈哈")
        mid = (left + right)//2
        if n > lst[mid]:
            left = mid + 1
            return func(n, left, right) # 递归  递归的入口
        elif n < lst[mid]:
            right = mid - 1
            # 深坑. 函数的返回值返回给调用者
            return func(n, left, right)    # 递归
        elif n == lst[mid]:
            print("找到了")
            return mid
            # return  # 通过return返回. 终止递归
    else:
        print("没有这个数") # 递归的出口
        return -1 # 1, 索引+ 2, 什么都不返回, None
# 找66, 左边界:0,  右边界是:len(lst) - 1
ret = func(70, 0, len(lst) - 1)
print(ret) # 不是None
递归完成二分查找
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)
切片二分法

切片二分法很难确定位置

3.给一x位数,2**n    最多要查找n次  时间复杂度 o(1)~o(n)

七.最快速的查询讯方式(时间复杂度最低,空间复杂度最低)

  查询某个元素是否在某个序列中

lst1 = [5,6,7,8]

lst2 = [0,0,0,0,0,0,0,0,0]  #9个0

for el in lst1:

  lst2[el] = 1

o(1) #时间复杂度是1

解释: 查询某列表中lst是否存在某个元素a,

  1.先建立一个列表,列表中有lst中最大值加1个零

  2.当lst2[a] == 1是该元素存在列表中,当lst2[a]==0时该元素不存在列表中

八总结

filter()和map()一样得到的是地址,需要遍历才能得到结果

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!