我写了一个继承自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个列表循环,但我找不到其他方式
答案 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等系统;那些可以为你处理过期的旧数据。