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

本文实例讲述了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程序设计有所帮助。

(0)

相关推荐

  • Python聚类算法之凝聚层次聚类实例分析

    本文实例讲述了Python聚类算法之凝聚层次聚类.分享给大家供大家参考,具体如下: 凝聚层次聚类:所谓凝聚的,指的是该算法初始时,将每个点作为一个簇,每一步合并两个最接近的簇.另外即使到最后,对于噪音点或是离群点也往往还是各占一簇的,除非过度合并.对于这里的"最接近",有下面三种定义.我在实现是使用了MIN,该方法在合并时,只要依次取当前最近的点对,如果这个点对当前不在一个簇中,将所在的两个簇合并就行: 单链(MIN):定义簇的邻近度为不同两个簇的两个最近的点之间的距离. 全链(MAX

  • Python聚类算法之DBSACN实例分析

    本文实例讲述了Python聚类算法之DBSACN.分享给大家供大家参考,具体如下: DBSCAN:是一种简单的,基于密度的聚类算法.本次实现中,DBSCAN使用了基于中心的方法.在基于中心的方法中,每个数据点的密度通过对以该点为中心以边长为2*EPs的网格(邻域)内的其他数据点的个数来度量.根据数据点的密度分为三类点: 核心点:该点在邻域内的密度超过给定的阀值MinPs. 边界点:该点不是核心点,但是其邻域内包含至少一个核心点. 噪音点:不是核心点,也不是边界点. 有了以上对数据点的划分,聚合可

  • Python实现约瑟夫环问题的方法

    本文实例讲述了Python实现约瑟夫环问题的方法.分享给大家供大家参考,具体如下: 题目:0,1,...,n-1这n个数字排成一个圆圈,从数字0开始每次从这个圆圈里删除第m个数字.求出这个圆圈里剩下的最后一个数字. 定义函数f(n,m),表示每次在n个数字(0,1,...,n-1)中每次删除第m个数字后最后剩下的数字. 在n个数字中,假设第一个被删除的数字为k,那么删除k之后剩下的n-1个数字为0~k-1,k 1~n-1,并且下一次删除从数字k 1开始计数.第二个序列最后剩下的数字也就是我们要求

  • python装饰器与递归算法详解

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说明一下: 小P闲来无事,随便翻看自己以前写的一些函数,忽然对一个最最最基础的函数起了兴趣: def sum1(): sum = 1 + 2 print(sum) sum1() 此时小P想看看这个函数执行用了多长时间,所以写了几句代码插进去了: import time def sum1(): star

  • python超简单解决约瑟夫环问题

    本文实例讲述了python超简单解决约瑟夫环问题的方法.分享给大家供大家参考.具体分析如下: 约瑟环问题大家都熟悉.题目是这样的.一共有三十个人,从1-30依次编号.每次隔9个人就踢出去一个人.求踢出的前十五个人的号码: 明显的约瑟夫环问题,python实现代码如下: a = [ x for x in range(1,31) ] #生成编号 del_number = 8 #该删除的编号 for i in range(15): print a[del_number] del a[del_numbe

  • python实现RSA加密(解密)算法

    RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准. 今天只有短的RSA钥匙才可能被强力方式解破.到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式.只要其密钥的长度足够长,用RSA加密的信息实际上是不能被解破的.但在分布式计算和量子计算机理论日趋成熟的今天,RSA加密安全性受到了挑战. RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥.

  • python实现中文分词FMM算法实例

    本文实例讲述了python实现中文分词FMM算法.分享给大家供大家参考.具体分析如下: FMM算法的最简单思想是使用贪心算法向前找n个,如果这n个组成的词在词典中出现,就ok,如果没有出现,那么找n-1个...然后继续下去.假如n个词在词典中出现,那么从n+1位置继续找下去,直到句子结束. import re def PreProcess(sentence,edcode="utf-8"): sentence = sentence.decode(edcode) sentence=re.s

  • 八大排序算法的Python实现

    Python实现八大排序算法,具体内容如下 1.插入排序 描述 插入排序的基本操作就是将一个数据插入到已经排好序的有序数据中,从而得到一个新的.个数加一的有序数据,算法适用于少量数据的排序,时间复杂度为O(n^2).是稳定的排序方法.插入算法把要排序的数组分成两部分:第一部分包含了这个数组的所有元素,但将最后一个元素除外(让数组多一个空间才有插入的位置),而第二部分就只包含这一个元素(即待插入元素).在第一部分排序完成后,再将这个最后元素插入到已排好序的第一部分中. 代码实现 def inser

  • Python字符串匹配算法KMP实例

    本文实例讲述了Python字符串匹配算法KMP.分享给大家供大家参考.具体如下: #!/usr/bin/env python #encoding:utf8 def next(pattern): p_len = len(pattern) pos = [-1]*p_len j = -1 for i in range(1, p_len): while j > -1 and pattern[j+1] != pattern[i]: j = pos[j] if pattern[j+1] == pattern

  • 约瑟夫问题的Python和C++求解方法

    么是约瑟夫问题? 约瑟夫问题是一个有趣的数学游戏,游戏规则如下: 1.N个人围成一个圈,编号从1开始,依次到N. 2.编号为M的游戏参与者开始报数,报数从1开始,后面的人报数接龙,直到K为止,报数为K的人将出局. 3.出局者的下一个玩家接着从1开始报数,如此循环,直到剩下一个玩家时游戏结束,这个玩家就是游戏获胜者. 那么问题来了,哪个编号是游戏获胜者呢? 下面通过简单的几行python代码来解决这个问题: #!/usr/bin/env python # Joseph Problem def jo

  • 使用python实现rsa算法代码

    RSA算法是一种非对称加密算法,是现在广泛使用的公钥加密算法,主要应用是加密信息和数字签名. 维基百科给出的RSA算法简介如下: 假设Alice想要通过一个不可靠的媒体接收Bob的一条私人讯息.她可以用以下的方式来产生一个公钥和一个私钥: 随意选择两个大的质数p和q,p不等于q,计算N=pq. 根据欧拉函数,不大于N且与N互质的整数个数为(p-1)(q-1) 选择一个整数e与(p-1)(q-1)互质,并且e小于(p-1)(q-1) 用以下这个公式计算d:d × e ≡ 1 (mod (p-1)(

  • 以Python代码实例展示kNN算法的实际运用

    邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表. kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性.该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别. kNN方法在类别决策时,只与极少量的相邻样本有关.由于kNN方法主

随机推荐