Python实现的最近最少使用算法


Posted in Python onJuly 10, 2015

本文实例讲述了Python实现的最近最少使用算法。分享给大家供大家参考。具体如下:

# lrucache.py -- a simple LRU (Least-Recently-Used) cache class 
# Copyright 2004 Evan Prodromou <evan@bad.dynu.ca> 
# Licensed under the Academic Free License 2.1 
# Licensed for ftputil under the revised BSD license 
# with permission by the author, Evan Prodromou. Many 
# thanks, Evan! :-) 
# 
# The original file is available at 
# http://pypi.python.org/pypi/lrucache/0.2 . 
# arch-tag: LRU cache main module 
"""a simple LRU (Least-Recently-Used) cache module 
This module provides very simple LRU (Least-Recently-Used) cache 
functionality. 
An *in-memory cache* is useful for storing the results of an 
'expe\nsive' process (one that takes a lot of time or resources) for 
later re-use. Typical examples are accessing data from the filesystem, 
a database, or a network location. If you know you'll need to re-read 
the data again, it can help to keep it in a cache. 
You *can* use a Python dictionary as a cache for some purposes. 
However, if the results you're caching are large, or you have a lot of 
possible results, this can be impractical memory-wise. 
An *LRU cache*, on the other hand, only keeps _some_ of the results in 
memory, which keeps you from overusing resources. The cache is bounded 
by a maximum size; if you try to add more values to the cache, it will 
automatically discard the values that you haven't read or written to 
in the longest time. In other words, the least-recently-used items are 
discarded. [1]_ 
.. [1]: 'Discarded' here means 'removed from the cache'. 
"""
from __future__ import generators 
import time 
from heapq import heappush, heappop, heapify 
# the suffix after the hyphen denotes modifications by the 
# ftputil project with respect to the original version 
__version__ = "0.2-1"
__all__ = ['CacheKeyError', 'LRUCache', 'DEFAULT_SIZE'] 
__docformat__ = 'reStructuredText en'
DEFAULT_SIZE = 16
"""Default size of a new LRUCache object, if no 'size' argument is given."""
class CacheKeyError(KeyError): 
  """Error raised when cache requests fail 
  When a cache record is accessed which no longer exists (or never did), 
  this error is raised. To avoid it, you may want to check for the existence 
  of a cache record before reading or deleting it."""
  pass
class LRUCache(object): 
  """Least-Recently-Used (LRU) cache. 
  Instances of this class provide a least-recently-used (LRU) cache. They 
  emulate a Python mapping type. You can use an LRU cache more or less like 
  a Python dictionary, with the exception that objects you put into the 
  cache may be discarded before you take them out. 
  Some example usage:: 
  cache = LRUCache(32) # new cache 
  cache['foo'] = get_file_contents('foo') # or whatever 
  if 'foo' in cache: # if it's still in cache... 
    # use cached version 
    contents = cache['foo'] 
  else: 
    # recalculate 
    contents = get_file_contents('foo') 
    # store in cache for next time 
    cache['foo'] = contents 
  print cache.size # Maximum size 
  print len(cache) # 0 <= len(cache) <= cache.size 
  cache.size = 10 # Auto-shrink on size assignment 
  for i in range(50): # note: larger than cache size 
    cache[i] = i 
  if 0 not in cache: print 'Zero was discarded.' 
  if 42 in cache: 
    del cache[42] # Manual deletion 
  for j in cache:  # iterate (in LRU order) 
    print j, cache[j] # iterator produces keys, not values 
  """
  class __Node(object): 
    """Record of a cached value. Not for public consumption."""
    def __init__(self, key, obj, timestamp, sort_key): 
      object.__init__(self) 
      self.key = key 
      self.obj = obj 
      self.atime = timestamp 
      self.mtime = self.atime 
      self._sort_key = sort_key 
    def __cmp__(self, other): 
      return cmp(self._sort_key, other._sort_key) 
    def __repr__(self): 
      return "<%s %s => %s (%s)>" % \ 
          (self.__class__, self.key, self.obj, \ 
          time.asctime(time.localtime(self.atime))) 
  def __init__(self, size=DEFAULT_SIZE): 
    # Check arguments 
    if size <= 0: 
      raise ValueError, size 
    elif type(size) is not type(0): 
      raise TypeError, size 
    object.__init__(self) 
    self.__heap = [] 
    self.__dict = {} 
    """Maximum size of the cache. 
    If more than 'size' elements are added to the cache, 
    the least-recently-used ones will be discarded."""
    self.size = size 
    self.__counter = 0
  def _sort_key(self): 
    """Return a new integer value upon every call. 
    Cache nodes need a monotonically increasing time indicator. 
    time.time() and time.clock() don't guarantee this in a 
    platform-independent way. 
    """
    self.__counter += 1
    return self.__counter 
  def __len__(self): 
    return len(self.__heap) 
  def __contains__(self, key): 
    return self.__dict.has_key(key) 
  def __setitem__(self, key, obj): 
    if self.__dict.has_key(key): 
      node = self.__dict[key] 
      # update node object in-place 
      node.obj = obj 
      node.atime = time.time() 
      node.mtime = node.atime 
      node._sort_key = self._sort_key() 
      heapify(self.__heap) 
    else: 
      # size may have been reset, so we loop 
      while len(self.__heap) >= self.size: 
        lru = heappop(self.__heap) 
        del self.__dict[lru.key] 
      node = self.__Node(key, obj, time.time(), self._sort_key()) 
      self.__dict[key] = node 
      heappush(self.__heap, node) 
  def __getitem__(self, key): 
    if not self.__dict.has_key(key): 
      raise CacheKeyError(key) 
    else: 
      node = self.__dict[key] 
      # update node object in-place 
      node.atime = time.time() 
      node._sort_key = self._sort_key() 
      heapify(self.__heap) 
      return node.obj 
  def __delitem__(self, key): 
    if not self.__dict.has_key(key): 
      raise CacheKeyError(key) 
    else: 
      node = self.__dict[key] 
      del self.__dict[key] 
      self.__heap.remove(node) 
      heapify(self.__heap) 
      return node.obj 
  def __iter__(self): 
    copy = self.__heap[:] 
    while len(copy) > 0: 
      node = heappop(copy) 
      yield node.key 
    raise StopIteration 
  def __setattr__(self, name, value): 
    object.__setattr__(self, name, value) 
    # automagically shrink heap on resize 
    if name == 'size': 
      while len(self.__heap) > value: 
        lru = heappop(self.__heap) 
        del self.__dict[lru.key] 
  def __repr__(self): 
    return "<%s (%d elements)>" % (str(self.__class__), len(self.__heap)) 
  def mtime(self, key): 
    """Return the last modification time for the cache record with key. 
    May be useful for cache instances where the stored values can get 
    'stale', such as caching file or network resource contents."""
    if not self.__dict.has_key(key): 
      raise CacheKeyError(key) 
    else: 
      node = self.__dict[key] 
      return node.mtime 
if __name__ == "__main__": 
  cache = LRUCache(25) 
  print cache 
  for i in range(50): 
    cache[i] = str(i) 
  print cache 
  if 46 in cache: 
    print "46 in cache"
    del cache[46] 
  print cache 
  cache.size = 10
  print cache 
  cache[46] = '46'
  print cache 
  print len(cache) 
  for c in cache: 
    print c 
  print cache 
  print cache.mtime(46) 
  for c in cache: 
    print c

希望本文所述对大家的Python程序设计有所帮助。

Python 相关文章推荐
python启动办公软件进程(word、excel、ppt、以及wps的et、wps、wpp)
Apr 09 Python
详解Python验证码识别
Jan 25 Python
剖析Python的Twisted框架的核心特性
May 25 Python
Python利用带权重随机数解决抽奖和游戏爆装备问题
Jun 16 Python
Python 提取dict转换为xml/json/table并输出的实现代码
Aug 28 Python
python 根据正则表达式提取指定的内容实例详解
Dec 04 Python
Python实现复杂对象转JSON的方法示例
Jun 22 Python
使用python实现接口的方法
Jul 07 Python
Python爬虫实例扒取2345天气预报
Mar 04 Python
python 实现在一张图中绘制一个小的子图方法
Jul 07 Python
浅谈keras 的抽象后端(from keras import backend as K)
Jun 16 Python
Python使用socket_TCP实现小文件下载功能
Oct 09 Python
Python导入oracle数据的方法
Jul 10 #Python
Python验证码识别的方法
Jul 10 #Python
Python实现大文件排序的方法
Jul 10 #Python
Python实现telnet服务器的方法
Jul 10 #Python
Python读写unicode文件的方法
Jul 10 #Python
Python实现提取谷歌音乐搜索结果的方法
Jul 10 #Python
python和bash统计CPU利用率的方法
Jul 10 #Python
You might like
PHP错误Parse error: syntax error, unexpected end of file in test.php on line 12解决方法
2014/06/23 PHP
函数中使用require_once问题深入探讨 优雅的配置文件定义方法推荐
2014/07/02 PHP
PHP实现JS中escape与unescape的方法
2016/07/11 PHP
JS查看对象功能代码
2008/04/25 Javascript
Mozilla 表达式 __noSuchMethod__
2009/04/05 Javascript
javascript 简单抽屉效果的实现代码
2010/03/09 Javascript
jQuery中not()方法用法实例
2015/01/06 Javascript
JavaScript对数组进行随机重排的方法
2015/07/22 Javascript
APP中javascript+css3实现下拉刷新效果
2016/01/27 Javascript
Bootstrap响应式侧边栏改进版
2016/09/17 Javascript
老生常谈Javascript中的原型和this指针
2016/10/09 Javascript
JavaScript之RegExp_动力节点Java学院整理
2017/06/29 Javascript
javascript浏览器用户代理检测脚本实现方法
2017/10/27 Javascript
Angular2进阶之如何避免Dom误区
2018/04/02 Javascript
原生js实现简单轮播图
2020/10/26 Javascript
linux系统使用python监测网络接口获取网络的输入输出
2014/01/15 Python
python实现获取序列中最小的几个元素
2014/09/25 Python
Python中使用glob和rmtree删除目录子目录及所有文件的例子
2014/11/21 Python
Python标准库defaultdict模块使用示例
2015/04/28 Python
Python中用altzone()方法处理时区的教程
2015/05/22 Python
举例讲解Python编程中对线程锁的使用
2016/07/12 Python
详解Python里使用正则表达式的ASCII模式
2017/11/02 Python
CentOS7安装Python3的教程详解
2019/04/10 Python
python 实现dict转json并保存文件
2019/12/05 Python
Django表单提交后实现获取相同name的不同value值
2020/05/14 Python
python使用建议与技巧分享(一)
2020/08/17 Python
html特殊符号示例 html特殊字符编码对照表
2014/01/14 HTML / CSS
施华洛世奇英国官网:SWAROVSKI英国
2017/03/13 全球购物
电子专业推荐信范文
2013/11/18 职场文书
2014年情人节活动方案
2014/02/16 职场文书
公司总经理助理岗位职责
2014/07/09 职场文书
宾馆仓管员岗位职责
2014/07/27 职场文书
员工拾金不昧表扬稿
2015/05/05 职场文书
初中化学教学反思
2016/02/22 职场文书
Pytorch可视化的几种实现方法
2021/06/10 Python
用python修改excel表某一列内容的操作方法
2021/06/11 Python