2

我写了一个继承自dict的类,我写了一个成员方法来删除对象。

class RoleCOList(dict):
    def __init__(self):
        dict.__init__(self)

    def recyle(self):
        '''
        remove roles too long no access
        '''
        checkTime = time.time()-60*30
        l = [k for k,v in self.items() if v.lastAccess>checkTime]
        for x in l:
            self.pop(x)

是不是太低效了?我使用了 2 个列表循环,但我找不到其他方法

4

5 回答 5

3

在去年的 SciPy 会议上,我参加了一个演讲,演讲者说了这句话,any()并且all()是循环完成任务的快速方法。这说得通; 循环for在每次迭代时重新绑定循环变量,而any()简单all()地使用该值。

显然,any()当您想要运行一个总是返回错误值的函数时使用,例如None. 这样,整个循环将运行到最后。

checkTime = time.time() - 60*30

# use any() as a fast way to run a loop
# The .__delitem__() method always returns `None`, so this runs the whole loop
lst = [k for k in self.keys() if self[k].lastAccess > checkTime]
any(self.__delitem__(k) for k in lst)
于 2012-11-08T20:11:56.373 回答
1

那这个呢?

_ = [self.pop(k) for k,v in self.items() if v.lastAccess>checkTime]
于 2012-11-08T04:12:20.457 回答
1

由于您不需要生成的列表,因此您可以使用生成器和此消费配方中的片段。特别是,用于collections.deque为您运行一个生成器。

checkTime = time.time()-60*30

# Create a generator for all the values you will age off
age_off = (self.pop(k) for k in self.keys() if self[k].lastAccess>checkTime)

# Let deque handle iteration (in one shot, with little memory footprint)
collections.deque(age_off,maxlen=0)

由于在 age_off 的迭代过程中字典发生了变化,因此使用self.keys()which 返回一个列表。(使用self.iteritems()将引发一个RuntimeError。)

于 2012-11-08T04:18:45.727 回答
0

我的(完全不可读的解决方案):

from operator import delitem
map(lambda k: delitem(self,k), filter(lambda k: self[k].lastAccess<checkTime, iter(self)))

但至少它应该是相当节省时间和内存的;-)

于 2012-11-08T04:48:43.550 回答
0

如果性能是一个问题,并且如果您将拥有大量数据,您可能需要考虑将 Python 前端用于 memcached 或 redis 等系统;那些可以为您处理过期的旧数据。

http://memcached.org/

http://pypi.python.org/pypi/python-memcached/

http://redis.io/

https://github.com/andymccurdy/redis-py

于 2012-11-08T20:38:20.240 回答