码迷,mamicode.com
首页 > 编程语言 > 详细

LRU算法的Python实现

时间:2015-06-05 21:07:54      阅读:166      评论:0      收藏:0      [点我收藏+]

标签:

    LRU:least recently used,最近最少使用算法。它的使用场景是:在有限的空间中存储对象时,当空间满时,会一定的原则删除原有的对象,常用的原则(算法)有LRU,FIFO,LFU等。在计算机的Cache硬件,以及主存到虚拟内存的页面置换,还有Redis缓存系统中都用到了该算法。我在一次面试和一个笔试时,都遇到过这个问题。

    LRU的算法是比较简单的,当对key进行访问时(一般有查询,更新,增加,在get()和set()两个方法中实现即可)时,将该key放到队列的最前端(或最后端)就行了,这样就实现了对key按其最后一次访问的时间降序(或升序)排列。

    在Python中,可以使用collections.OrderedDict很方便的实现LRU算法,当然,如果你想不到用OrderedDict,那可以自己用dict+list来实现。本文主要参考了LRU CACHE IN PYTHON,写的非常好,既实现了功能,又简洁易读。方法一的代码与参考文章基本相同,方法二是我自己想出来的,比较繁琐一些,其实OrderedDict本身也是类似的这种机制来实现的有序。

 

方法一:用OrderedDict实现(推荐)

from collections import OrderedDict
 
 
class LRUCache(OrderedDict):
     
    def __init__(self,capacity):
        self.capacity = capacity
        self.cache = OrderedDict()
     

    def get(self,key):
        if self.cache.has_key(key):
            value = self.cache.pop(key)
            self.cache[key] = value
        else:
            value = None
         
        return value
     

    def set(self,key,value):
        if self.cache.has_key(key):
            value = self.cache.pop(key)
            self.cache[key] = value
        else:
            if len(self.cache) == self.capacity:
                self.cache.popitem(last = False)    #pop出第一个item
                self.cache[key] = value
            else:
                self.cache[key] = value

 

测试代码如下

c = LRUCache(5)
  
for i in range(5,10):
    c.set(i,10*i)
  
  
print c.cache, c.cache.keys()
  
c.get(5)
c.get(7)
  
print c.cache, c.cache.keys()
  
c.set(10,100)
print c.cache, c.cache.keys()
  
c.set(9,44)
print c.cache, c.cache.keys()

输出如下

OrderedDict([(5, 50), (6, 60), (7, 70), (8, 80), (9, 90)])     [5, 6, 7, 8, 9]
OrderedDict([(6, 60), (8, 80), (9, 90), (5, 50), (7, 70)])     [6, 8, 9, 5, 7]
OrderedDict([(8, 80), (9, 90), (5, 50), (7, 70), (10, 100)])   [8, 9, 5, 7, 10]
OrderedDict([(8, 80), (5, 50), (7, 70), (10, 100), (9, 90)])   [8, 5, 7, 10, 9]

 

 

方法二:用dict+list实现(不推荐)

class LRUCache(object):
      
    def __init__(self,capacity):
        self.l = []
        self.d = {}
        self.capacity = capacity
          
def get(self,key): if self.d.has_key(key): value = self.d[key] self.l.remove(key) self.l.insert(0,key) else: value = None return value
def set(self,key,value): if self.d.has_key(key): self.l.remove(key) elif len(self.d) == self.capacity: oldest_key = self.l.pop() self.d.pop(oldest_key) self.d[key] = value self.l.insert(0, key)

测试代码如下

c = LRUCache(5)
  
for i in range(5,10):
    c.set(i,10*i)
  
  
print c.d,c.l
  
c.get(5)
c.get(7)
  
print c.d,c.l
  
c.set(10,100)
print c.d,c.l
  
c.set(9,44)
print c.d,c.l

输出为

{8: 80, 9: 90, 5: 50, 6: 60, 7: 70}   [9, 8, 7, 6, 5]
{8: 80, 9: 90, 5: 50, 6: 60, 7: 70}   [7, 5, 9, 8, 6]
{5: 50, 7: 70, 8: 80, 9: 90, 10: 100} [10, 7, 5, 9, 8]
{5: 50, 7: 70, 8: 80, 9: 44, 10: 100} [9, 10, 7, 5, 8]

 

参考:

http://www.kunxi.org/blog/2014/05/lru-cache-in-python/

http://blog.sina.com.cn/s/blog_631d3a630101mhup.html

 

LRU算法的Python实现

标签:

原文地址:http://www.cnblogs.com/ajianbeyourself/p/4555560.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!