这是删除dict中对象的正确方法

时间:2012-11-08 03:58:19

标签: python python-3.x

我写了一个继承自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个列表循环,但我找不到其他方式

5 个答案:

答案 0 :(得分:3)

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

显然,如果要运行始终返回false值的函数,例如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)

答案 1 :(得分:1)

这是怎么回事?

_ = [self.pop(k) for k,v in self.items() if v.lastAccess>checkTime]

答案 2 :(得分:1)

由于您不需要生成的列表,因此您可以使用此consume recipe中的生成器和代码段。特别是,使用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()。 (使用self.iteritems()会引发RuntimeError。)

答案 3 :(得分:0)

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

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

但至少应该是时间和记忆效率很高; - )

答案 4 :(得分:0)

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

http://memcached.org/

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

http://redis.io/

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