再谈Python的高阶函数和装饰器笔记(1)

    技术2022-07-10  160

    高阶函数:我的理解就是闭包、内嵌函数

    举例:

    计数器:

    有问题么?

    问题出在base+=step,对base赋值,局部变量,没有先定义

    改进:声明为非局部变量nonlocal,但是不要是global变量

    观察一下:

    id(f1)

    id(f2)

    f1==f2

    自定义sort函数:

    以下是加入reverse参数的改进:推荐flag的用法

    改写为高阶函数,注意comp函数:

    comp函数比较通用。可以抽象出来。如下:

    再改写成高阶函数形式:

    先简化一下comp函数,使其不带reverse参数:

    替换成sort自己的调用:

    再进一步改造comp函数为匿名函数lambda a,b:a<b

    再改造一下,去掉reverse参数吗,由匿名函数比较关系决定升序还是降序


    #%% #最原始的排序 lst=[1,2,5,4,2,3,5,6] def sort(iterable):     ret=[]     for x in iterable:         for i,y in enumerate(ret):             if x>y:                 ret.insert(i,x)                 break         else:             ret.append(x)     return ret

    sort(lst)

    #%% #加入reverse参数,控制升序、降序,添加flag标志 lst=[1,2,5,4,2,3,5,6] def sort(iterable,reverse=False):     ret=[]     for x in iterable:         for i,y in enumerate(ret):             flag=x>y  if reverse else x<y             if flag:                 ret.insert(i,x)                 break         else:             ret.append(x)     return ret

    sort(lst,True)

    #%% #嵌套函数,实现判断 lst=[1,2,5,4,2,3,5,6] def sort(iterable,reverse=False):     def cmp(a,b):        flag=a>b  if reverse else a<b        return flag     ret=[]     for x in iterable:         for i,y in enumerate(ret):             if cmp(x,y):                 ret.insert(i,x)                 break         else:             ret.append(x)     return ret

    sort(lst,False)

    #%% #把嵌套函数提取出来,成为公共函数 lst=[1,2,5,4,2,3,5,6] def cmp(a,b,reverse=False):    flag=a>b  if reverse else a<b    return flag def sort(iterable):     ret=[]     for x in iterable:         for i,y in enumerate(ret):             if cmp(x,y,True):                 ret.insert(i,x)                 break         else:             ret.append(x)     return ret

    sort(lst)

    #%% #把函数作为参数,设计高阶函数 lst=[1,2,5,4,2,3,5,6] def cmp(a,b,reverse=False):    return a>b  if reverse else a<b def sort(iterable,key=cmp,reverse=False):     ret=[]     for x in iterable:         for i,y in enumerate(ret):             if key(x,y,reverse):                 ret.insert(i,x)                 break         else:             ret.append(x)     return ret

    sort(lst,reverse=True)

     

    #%% #去掉公共函数的reverse参数,由主函数reverse控制升降序 lst=[1,2,5,4,2,3,5,6] def cmp(a,b):    return a>b def sort(iterable,key=cmp,reverse=False):     ret=[]     for x in iterable:         for i,y in enumerate(ret):             flag=key(x,y) if reverse else key(y,x)             if flag:                 ret.insert(i,x)                 break         else:             ret.append(x)     return ret

    sort(lst,reverse=True)

    #%% #去掉公共函数。利用lambda匿名函数 lst=[1,2,5,4,2,3,5,6] def cmp(a,b):    return a>b def sort(iterable,key=lambda a,b:a>b,reverse=False):     ret=[]     for x in iterable:         for i,y in enumerate(ret):             flag=key(x,y) if reverse else key(y,x)             if flag:                 ret.insert(i,x)                 break         else:             ret.append(x)     return ret

    sort(lst,reverse=False)

    #%% #继续优化,利用匿名函数去电reverse参数 lst=[1,2,5,4,2,3,5,6]

    def sort(iterable,key=lambda a,b:a>b):     ret=[]     for x in iterable:         for i,y in enumerate(ret):             if key(x,y):                 ret.insert(i,x)                 break         else:             ret.append(x)     return ret

    sort(lst,lambda a,b:a<b)

     

     


    知识点补充:enumerate、集合set操作

    >>> import random >>> l=[random.randint(1,100) for i in range(5)] >>> l [10, 14, 62, 30, 45]

    >>> print(list(enumerate(l))) [(0, 10), (1, 14), (2, 62), (3, 30), (4, 45)] >>> for e in enumerate(l):     print(e[0])    0 1 2 3 4

    >>> for i,x in enumerate(l):     print(i,'   ',x) 0     10 1     14 2     62 3     30 4     45

    >>> k=set(l) >>> k {10, 45, 14, 30, 62}

     |  add(...)  |      Add an element to a set.  |        |      This has no effect if the element is already present.  |    |  clear(...)  |      Remove all elements from this set.  |    |  copy(...)  |      Return a shallow copy of a set.  |    |  difference(...)  |      Return the difference of two or more sets as a new set.

     

     

     

     

     

     

     

     

     

    Processed: 0.011, SQL: 9