Python 从计数器中删除最不常用的元素
在值小于某个值的计数器中,是否有“更快的方法”来删除键、值对 我已经做了以下工作:Python 从计数器中删除最不常用的元素,python,counter,Python,Counter,在值小于某个值的计数器中,是否有“更快的方法”来删除键、值对 我已经做了以下工作: counter_dict = {k:v for k, v in counter_dict.items() if v > 5} 当前代码的主要问题是调用.items,这将创建所有项目的列表: 一种优化方法是使用而不是.items,以避免创建列表并再次遍历列表的代价 >>> from collections import Counter >>> cnt = Counter(
counter_dict = {k:v for k, v in counter_dict.items() if v > 5}
当前代码的主要问题是调用
.items
,这将创建所有项目的列表:
一种优化方法是使用而不是.items
,以避免创建列表并再次遍历列表的代价
>>> from collections import Counter
>>> cnt = Counter("asbdasdbasdbadaasasdasadsa")
>>> {k:v for k,v in cnt.iteritems() if v > 5}
{'a': 10, 's': 7, 'd': 6}
另一种优化可能是不调用.items
方法,而是迭代键并使用键访问值:
>>> from collections import Counter
>>> cnt = Counter("asbdasdbasdbadaasasdasadsa")
>>> {k:cnt[k] for k in cnt if cnt[k] > 5}
{'a': 10, 's': 7, 'd': 6}
如果我们尝试使用ipython中的
%timeit
测量差异,使用带有您提到的If条件的样本计数器,
将轻松获胜:
In [1]: import random
In [2]: from collections import Counter
In [3]: MILLION = 10**6
In [4]: cnt = Counter(random.randint(0, MILLION) for _ in xrange(MILLION))
In [5]: %timeit {k:v for k, v in cnt.iteritems() if v < 5}
10 loops, best of 3: 140 ms per loop
In [6]: %timeit {k:v for k, v in cnt.items() if v**2 < 5}
1 loops, best of 3: 290 ms per loop
In [7]: %timeit {k:cnt[k] for k in cnt if cnt[k] < 5}
1 loops, best of 3: 272 ms per loop
因此,您最好不要每次都重新创建整个词典:
to_remove = set()
for key, value in counter_dict.viewitems():
if value <= 5:
to_remove.add(key)
for key in to_remove:
del counter_dict[key]
当dict应该开始过滤时,更改dict中的“阈值”属性对象。这或多或少有些过火了-因为您的检查仍将完成,只是时间会被稀释-但可能在使用对象时,您处于异步/多线程工作负载上,这可能会使其并行-但是如果您在代码的不同部分需要不同的阈值,这可能是一件好事。您是否有特殊的性能问题?是的。柜台可以容纳超过500000个物品。根据10000个电话的调查显示,你的回答速度更快@mu比较慢,0.416秒,你的建议是0.715秒。
to_remove = set()
for key, value in counter_dict.viewitems():
if value <= 5:
to_remove.add(key)
for key in to_remove:
del counter_dict[key]
class MyDict(dict):
def __init__(*args, **kw):
self.threshold = None
super(MyDict,self).__init__(*args, **kw)
def __getitem__(self, key):
value = super(MyDict, self).__getitem__(key)
if self.threshold is None or key > self.threshold:
return value
raise ItemError
# the same for __contains__ and other interesting methods