装饰器python的通俗理解_2道极好的Python算法题 | 带你透彻理解装饰器的妙用
今天我分享两道非常好的算法题,大家耐心看完两道算法题之后,注意精华在最后,我相信大家对装饰器的理解又会更上一层楼.
1.斐波那契数列
1).这个序列非常有名,我非常喜欢这个序列(有同学问我为啥,偷偷告诉大家,这个序列帮了我不少忙,等下半年我写数据分析文章的时候,会跟大家分享心得)
这个序列也叫兔子序列,网上有很多关于这个序列的解法,我们就直接上代码
我们用推导列表把兔子序列前10项打印出来,有同学说这个跟装饰器有毛关系,不要急,如果我们若打印40项,看看需要花多少时间
import time
start=time.time()
[fib(n) for n in range(40)]
end=time.time()
print 'cost:{}'.format(end-start)
>>
cost:150.200000048
如果我们打印50项,则需要花更多的时间,光40项需要花150多秒,50项就更长了.难是因为这个运算量太大了吗,NONONO,是因为我们算法没有经过优化。
看上面这张图,你会发现我们在计算兔子序列的时候,有大量重复的计算,比如算F(10)=F(9)+F(8),F(9)=F(8)+F(7),F(8)需要重复计算两次~~
怎么破,很容易想到我们需要用一个缓存,把这个计算过的数字存在一个表里面,用的时候若这个数字在这个表,就不用再花cpu去运算,直接取就好了。
2).先把上面的代码改一下,我们申明一个count变量,每次递归都存起来,然后最后再返回
3).接着演变,我们现在构造一个缓冲区cache
我们查表,比如用字典来保存,比如cache[8]=34,我们只需要查一下8是不是在字典里面就可以了,在的话直接取,不在的话再去用算法计算,是不是很爽
看运行40项,几乎不费吹灰之力,非常快
2.爬楼梯
比如我有7阶台阶,我们可以用两种爬发,一次一步或者两步,只能进不能退,算算有多少种爬法
我们先简单分析一下:
若只有一阶台阶,那么不管是一次选择一步还是两步,都只有一种爬法
若只有两阶台阶,选择一步or两步,会有两种爬法
若只有三阶台阶,选择一步然后一步然后一步,或者一步,两步,或者两步,一步,这样有3种爬法
若只有四阶台阶,选择一步,然后剩下3阶台阶的爬法,这3阶爬法可以直接取前面3阶台阶的计算结果
我们先写源码,源码很简单用递归搞定,首先设计递归的出口,当只有1阶或者小于1阶台阶时候,直接return 1
大家有没有发现这个爬楼梯一样存在重复计算的问题,比如5阶的时候,一步一步然后剩下3步,或者两步然后剩下3步
一样需要用到兔子序列的cache方法,那么在climb函数中再重复写一篇,是不是很累赘,这不是Pythonic的风格,有没有比较好的封装方法呢,同时又能不改动原始的代码呢~~有的,牛逼闪闪的Python当然有,就是我们的装饰器啦,好我们看装饰器如何封装搞定
3.装饰器封装
对于兔子序列和爬楼梯,我们用装饰器去封装一下,怎么封装呢,我们一步一步来,参考上一篇入门很容易构建出来
1).创建一个装饰器
def decorate(func):
cache={}
def wrap(n):
if n not in cache:
cache[n]=func(n)
return cache[n]
return wrap
2).装饰一下斐波那契数列
是不是很简洁,装饰器真是个好东西啊~~
3).装饰器参数升级
大家有没有发现我们上面构造的装饰器,入参是一个参数n.如果碰到需要传入的多个参数的函数怎么办,比如我们的爬楼梯原函数就是2个参数,所以我们需要把装饰器写更通俗一点,对用变参
留几个问题:
1.print climb(5,(1,2))为啥不是[1,2]
2.为啥不能加else
def decorator(func):
cache={}
def wrap(*args):
if args not in cache:
cache[args]=func(*args)
else:
return cache[args]
return wrap
3.加缓冲的时候
def fib(n,cache=None):
为啥不能写成def fib(n,cache={}):
好了装饰器的妙用就讲到这里,大家想一想如果我们还有类似的代码需要缓存机制,是不是只需要用装饰器封装一下就行了,是不是代码简洁很多而且容易维护和扩展功能,讲到这里大家是不是对装饰器的妙用有了进一步的理解,若有什么不懂的,也可以留言跟我探讨交流。
装饰器python的通俗理解_2道极好的Python算法题 | 带你透彻理解装饰器的妙用相关推荐
- rtosucos和linux区别,为什么我们需要uCos?带你透彻理解RTOS
原标题:为什么我们需要uCos?带你透彻理解RTOS 与uCos见面还是大学的时候,老师让我为毕业设计选一个课题,要求有关嵌入式实时操作系统,于是开始在网上搜索,顺理成章的就发现了uCos,于是开始了 ...
- python循环语句嵌套_2个实例搞懂Python循环嵌套——九九乘法表以及质数的索引...
前面我们讲过了Python中的循环语句有两种:while循环和for循环.Python语言可以允许在一个循环体内嵌套另一个循环体. 比如:在while循环中可以嵌套for循环:也可以在for循环中嵌套 ...
- 30道面试常见的数据结构算法题
注意: 边界条件的判断 取地址符传参的使用 溢出问题,long long 题目来源:https://github.com/ZXZxin/ZXBlog/blob/master/%E5%88%B7%E9% ...
- 为什么模电这么难学?一文带你透彻理解模电
想必模电就是小伙伴们非常头疼的一门课程,最深刻的感受莫过于就是"老师说第一遍不懂,第二遍还是不懂,第三遍还是不懂." 网友对模电有以下总结: 天书般难懂. 模电=魔电 本科模电就够 ...
- 15道使用频率极高的基础算法题
算法题列表 1.合并排序,将两个已经排序的数组合并成一个数组,其中一个数组能容下两个数组的所有元素; 2.合并两个已经排序的单链表; 3.倒序打印一个单链表; 4.给定一个单链表的头指针和一个指定节点 ...
- python为什么没有指针_Python 没有指针,如何解算法题?
- 求杨辉三角的前n行数据_两道简单的套公式算法题:杨辉三角
杨辉三角应该是大家很早就接触到的一个数学知识,它有很多有趣的性质: 每个数字等于上一行的左右两个数字之和,即 C(n+1,i) = C(n,i) + C(n,i-1) 每行数字左右对称,由 1 开始逐 ...
- 透彻理解BN(Batch Normalization)层
什么是BN Batch Normalization是2015年论文<Batch Normalization: Accelerating Deep Network Training by Redu ...
- 10个问题带你全面理解Linux性能优化
10个问题带你全面理解Linux性能优化 • Feiskyhttps://feisky.xyz/posts/2020-06-06-linux-perf/本文整理自极客时间"10个问题带你全面 ...
最新文章
- selector与layer-list 单边框效果
- .Net 中如何测试静态方法
- Java list三种遍历方法性能比较
- hadoop 基准测试与读写测试
- 算法训练营07-递归使用练习
- c#多线程同步之EventWaitHandle使用
- Python爬虫_BeauifulSoup
- python dataframe中缺失值处理
- 用户的大量数据保存在计算机的,计算机基础理论复习题
- 在macOS下制作黑苹果镜像
- 新萝卜家园 GhostXP_SP3 五一纪念版
- 什么是深度卷积神经网络,卷积神经网络怎么学
- 最新二次开发知宇自动发卡系统源码/全网对接/功能齐全
- 语音信号处理及特征提取
- 知识图谱下图神经网络、图计算、图数据、图数据库未来发展趋势如何?
- linux中文件颜色,蓝色,白色等各自代表的含义
- Android 去掉Power键屏保功能,但保留长按关机功能。
- 使用EditPlus技巧,提高工作效率(附英文版、自动完成文件、语法文件下载)(转载)...
- SVM分类器中损失函数梯度求法及理解
- 个网工获得CCNP认证后的成功求职记
热门文章
- 检查oracle安装必须包,Linux安装oracle11gR2官方步骤
- SpringBoot与SpringCloud集成
- 2021-10-07
- 图解算法系列笔记(三)
- note_maven中的常用命令
- 深度linux系统反复重启,修复启动
- micropython stm32f429_[MicroPython]STM32F407开发板驱动OLED液晶屏
- android 下拉刷新实现方式,Android RecyclerView设置下拉刷新的实现方法
- c语言中浮点数如何声明,C语言中浮点数定义和文本处理的配合
- ajax jsonp post php,※ajax的post方式注意点※及jsonp的封装