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

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

举例:

计数器:

有问题么?

问题出在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.

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值