• python之匿名函数、递归与二分法


    一、匿名函数

      什么是匿名函数?

        顾名思义就是没有名字的函数,在我们声明一个函数时会想起个什么函数名好,这个问题我想有时候会困惑大家的吧?   

    1 def func():  #正常函数声明
    2     pass
    3 print(func.__name__)
    4 #运行结果:func  
    5 
    6 
    7 a=lambda x:x*x  #匿名函数
    8 print(a.__name__)
    9 #运行结果:<lambda>

        而匿名函数并不是说一定没有名字,这里前面的变量a 就是一个函数名,说他是匿名函数是因为我们通过__name__方法查看的时候是没有名字的,统一为<lambda>

        所以我们叫它为匿名函数。

      匿名函数的特点:

        1.函数名的参数可以有多个,但多个参数之间用逗号隔开

        2.匿名函数不管多复杂,只能写一行(类似推导式),且逻辑结束后直接返回数据

        3.返回值和正常函数一样,可以是任意类型的数据

    二、递归与二分法

      

      利用一下这个有趣的图片,我们python中的递归就好比这个图片一样。在函数内部调用函数本身,这就是递归调用。

      

    1 def eat():
    2     print("吃饭")
    3     eat()
    4 eat()
    5 
    6 #在程序执行完可以看到有这样的错误maximum recursion depth exceeded while calling a Python object  意识就是说 调用Python对象时,最大递归深度超过了限制

       递归的特点:

          在递归时调用函数会产生局部的名称空间,占用内存,因为上述这种调用会无需调用本身,python解释器的内存管理机制为了防止其无限制占用内存,

      对函数的递归调用做了最大的层级限制:1000(可以通过设置改变) ,

      递归的用处无上限,能做你想不到的事情,或许也做不到你想做的事情。

      例如遍历一个文件夹中的所有文档:

     1 import os                #导入os模块
     2 def func(filepash,n):
     3     files=os.listdir(filepash)       #获取当前文件夹中的所有文件
     4     for file in files:        #遍历文件夹中的文件,这里只是获取本层文件名
     5         f_d=os.path.join(filepash,file)        #加人文件夹 获取文件夹+文件
     6         if os.path.isdir(f_d):          #如果改路径下的文件是文件夹
     7             print("	"*n,file)
     8             func(f_d,n+1)             #递归调用
     9         else:
    10             print("	"*n,file)        #递归出口
    11 func("f:/魔兽争霸3",0)        

      二分法

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

      核心思想:掐头去尾取中间,一次砍一半

     1 #当遇到一个无序列表时,就将二分法与冒泡排序结合使用
     2 lst=[1,65,136,98,64,98,794,654,98,76,465,49,751,]
     3 for i in range(len(lst)):
     4     for i in range(len(lst)-1):
     5         if lst[i]>lst[i+1]:
     6             lst[i],lst[i+1]=lst[i+1],lst[i]
     7 right=len(lst)-1                 #将右端看成尾部
     8 left=0                   #将左端看成头部
     9 n=465          
    10 while left<=right:
    11     mid = (right + left) // 2         #取一个中间值
    12     if n<lst[mid]:
    13         right=mid-1        #通过参数与中间值比较截取的一段
    14     if n>lst[mid]:
    15         left=mid+1
    16     if n ==lst[mid]:
    17         print("找到了")
    18         break
    19 else:
    20     print("未找到")    

      那我们既然学会了递归,就该活学活用利用递归思想来进行二分法

     1 lst=[1, 49, 64, 65, 76, 98, 98, 98, 136, 465, 654, 751, 794]       #前提是有序列表
     2 def func(n,left,right):
     3     mid = (left+right)//2
     4     if left<=right:
     5         if n < lst[mid]:
     6             right=mid-1
     7             return func(n,left,right)
     8         if n > lst[mid]:
     9             left=mid+1
    10             return func(n,left,right)
    11         if n==lst[mid]:
    12             print("找到了")
    13             return mid
    14     else:
    15         print("没找到")
    16         return -1
    17 print(func(465,0,len(lst)-1))

     

  • 相关阅读:
    Redis持久化
    Windows Phone中扩展WebBrowser使其支持绑定html内容
    使用MVVM-Sidekick开发Universal App(二)
    使用MVVM-Sidekick开发Universal App(一)
    在Windows Phone 8中使用Live Connect并保持登陆状态
    iOS 打印结构体
    CGAffineTransformMake 矩阵变换 的运算原理(转)
    二维码快速扫描工具
    微信小程序之wx.request:fail错误,真机预览请求无效问题解决,安卓,ios网络预览异常(转)
    UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释(转)
  • 原文地址:https://www.cnblogs.com/qq631243523/p/9482447.html
Copyright © 2020-2023  润新知