# 匿名函数
fib =lambda n:1if n <=1else fib(n-1)+ fib(n-2)# 将时间复杂度降低到线性
fib =lambda n, a=1, b=1: a if n ==0else fib(n-1, b, a+b)# 保证了匿名函数的匿名性
fib =lambda n, fib:1if n <=1else fib(n-1, fib)+ fib(n-2, fib)
defsteps_to(stair):if stair ==1:# You can reach the first stair with only a single step# from the floor.return1elif stair ==2:# You can reach the second stair by jumping from the# floor with a single two-stair hop or by jumping a single# stair a couple of times.return2elif stair ==3:# You can reach the third stair using four possible# combinations:# 1. Jumping all the way from the floor# 2. Jumping two stairs, then one# 3. Jumping one stair, then two# 4. Jumping one stair three timesreturn4else:# You can reach your current stair from three different places:# 1. From three stairs down# 2. From two stairs down# 2. From one stair down## If you add up the number of ways of getting to those# those three positions, then you should have your solution.return(
steps_to(stair -3)+ steps_to(stair -2)+ steps_to(stair -1))print(steps_to(4))
from functools import lru_cache
from timeit import repeat
@lru_cache(maxsize=16)defsteps_to(stair):if stair ==1:# You can reach the first stair with only a single step# from the floor.return1elif stair ==2:# You can reach the second stair by jumping from the# floor with a single two-stair hop or by jumping a single# stair a couple of times.return2elif stair ==3:# You can reach the third stair using four possible# combinations:# 1. Jumping all the way from the floor# 2. Jumping two stairs, then one# 3. Jumping one stair, then two# 4. Jumping one stair three timesreturn4else:# You can reach your current stair from three different places:# 1. From three stairs down# 2. From two stairs down# 2. From one stair down## If you add up the number of ways of getting to those# those three positions, then you should have your solution.return(
steps_to(stair -3)+ steps_to(stair -2)+ steps_to(stair -1))print(steps_to(30))print(steps_to.cache_info())
$ pip install feedparser requests
$ python monitor.py
Checking feed...
Fetching article from server...
The Real Python Podcast – Episode #28: Using ... 29520
Fetching article from server...
Python Community Interview With David Amos 54256
Fetching article from server...
Working With Linked Lists in Python 37099
Fetching article from server...
Python Practice Problems: Get Ready for Your ...164888
Fetching article from server...
The Real Python Podcast – Episode #27: Prepar... 30784
Checking feed...
Fetching article from server...
The Real Python Podcast – Episode #28: Using ... 29520
Fetching article from server...
Python Community Interview With David Amos 54256
Fetching article from server...
Working With Linked Lists in Python 37099
Fetching article from server...
Python Practice Problems: Get Ready for Your ...164888
Fetching article from server...
The Real Python Podcast – Episode #27: Prepar... 30784
$ python monitor.py
Checking feed...
Fetching article from server...
Match found: The Real Python Podcast – Episode #28: Using ... 29521
Fetching article from server...
Match found: Python Community Interview With David Amos 54254
Fetching article from server...
Match found: Working With Linked Lists in Python 37100
Fetching article from server...
Match found: Python Practice Problems: Get Ready for Your ...164887
Fetching article from server...
Match found: The Real Python Podcast – Episode #27: Prepar... 30783
Checking feed...
Match found: The Real Python Podcast – Episode #28: Using ... 29521
Match found: Python Community Interview With David Amos 54254
Match found: Working With Linked Lists in Python 37100
Match found: Python Practice Problems: Get Ready for Your ...164887
Match found: The Real Python Podcast – Episode #27: Prepar... 30783
Checking feed...
Match found: The Real Python Podcast – Episode #28: Using ... 29521
Match found: Python Community Interview With David Amos 54254
Match found: Working With Linked Lists in Python 37100
Match found: Python Practice Problems: Get Ready for Your ...164887
Match found: The Real Python Podcast – Episode #27: Prepar... 30783
Checking feed...
Fetching article from server...
Match found: The Real Python Podcast – Episode #28: Using ... 29521
Fetching article from server...
Match found: Python Community Interview With David Amos 54254
Fetching article from server...
Match found: Working With Linked Lists in Python 37099
Fetching article from server...
Match found: Python Practice Problems: Get Ready for Your ...164888
Fetching article from server...
Match found: The Real Python Podcast – Episode #27: Prepar... 30783
请注意,代码在第一次访问匹配的文章时是如何打印“Fetching article from server…”这条消息的。之后,根据网络速度和计算能力,脚本将从缓存中检索文章一两次,然后再次访问服务器。
deflru_cache(maxsize=128, typed=False):ifisinstance(maxsize,int):if maxsize <0:
maxsize =0elifcallable(maxsize)andisinstance(typed,bool):
user_function, maxsize = maxsize,128
wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)return update_wrapper(wrapper, user_function)elif maxsize isnotNone:raise TypeError('Expected first argument to be an integer, a callable, or None')defdecorating_function(user_function):
wrapper = _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo)return update_wrapper(wrapper, user_function)return decorating_function
_CacheInfo = namedtuple("CacheInfo",["hits","misses","maxsize","currsize"])def_lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo):
sentinel =object()# unique object used to signal cache misses
make_key = _make_key # build a key from the function arguments
PREV, NEXT, KEY, RESULT =0,1,2,3# names for the link fields
cache ={}# 存储也使用的字典
hits = misses =0
full =False
cache_get = cache.get
cache_len = cache.__len__
lock = RLock()# 因为双向链表的更新不是线程安全的所以需要加锁
root =[]# 双向链表
root[:]=[root, root,None,None]# 初始化双向链表if maxsize ==0:defwrapper(*args,**kwds):# No caching -- just a statistics updatenonlocal misses
misses +=1
result = user_function(*args,**kwds)return result
elif maxsize isNone:defwrapper(*args,**kwds):# Simple caching without ordering or size limitnonlocal hits, misses
key = make_key(args, kwds, typed)
result = cache_get(key, sentinel)if result isnot sentinel:
hits +=1return result
misses +=1
result = user_function(*args,**kwds)
cache[key]= result
return result
else:defwrapper(*args,**kwds):# Size limited caching that tracks accesses by recencynonlocal root, hits, misses, full
key = make_key(args, kwds, typed)with lock:
link = cache_get(key)if link isnotNone:# Move the link to the front of the circular queue
link_prev, link_next, _key, result = link
link_prev[NEXT]= link_next
link_next[PREV]= link_prev
last = root[PREV]
last[NEXT]= root[PREV]= link
link[PREV]= last
link[NEXT]= root
hits +=1return result
misses +=1
result = user_function(*args,**kwds)with lock:if key in cache:passelif full:
oldroot = root
oldroot[KEY]= key
oldroot[RESULT]= result
root = oldroot[NEXT]
oldkey = root[KEY]
oldresult = root[RESULT]
root[KEY]= root[RESULT]=Nonedel cache[oldkey]
cache[key]= oldroot
else:
last = root[PREV]
link =[last, root, key, result]
last[NEXT]= root[PREV]= cache[key]= link
full =(cache_len()>= maxsize)return result
defcache_info():"""Report cache statistics"""with lock:return _CacheInfo(hits, misses, maxsize, cache_len())defcache_clear():"""Clear the cache and cache statistics"""nonlocal hits, misses, full
with lock:
cache.clear()
root[:]=[root, root,None,None]
hits = misses =0
full =False
wrapper.cache_info = cache_info
wrapper.cache_clear = cache_clear
return wrapper