我有一本字典像这样:
my_dict=collections.OrderedDict([((123, 1), 'qwe'), ((232, 1), 'asd'), ((234, 2), 'zxc'), ((6745, 2), 'aaa'), ((456, 3), 'bbb')])
元组的组合始终是独特的,我想保持插入的顺序,因此OrderedDict。 我已经在字典一个超过〜10K项目。 我怎样才能有效地维护一个计数器,让元组的第二个元素的计数? 基本上,我需要知道,每当我想在关键的添加/删除项目计数。 现在,我只是通过遍历my_dict
和获取计数器每次但它似乎是这样做非常昂贵。
在上面的例子中,我想输出是:
1:2 # As in 1 occurs 2 times
2:2
3:1
现在我做到以下几点:
from collections import OrderedDict, Counter
my_dict = OrderedDict()
my_dict[(123,1)] = 'qwe'
my_dict[(232,1)] = 'asd'
my_dict[(234,2)] = 'zxc'
my_dict[(6745,2)] = 'aaa'
my_dict[(456,3)] = 'bbb'
cnt = []
for item in my_dict.keys():
cnt.append(item[1])
print Counter(cnt)
我不知道这是否是最好的方式,但有没有办法覆盖的=
运算符和pop
的功能,例如,它增加或我每次做的工作时间减去计数?
获取一个Counter
与一个很好地工作OrderedDict
很可能将需要一些子类。 这里的东西可能工作(我只实现__setitem__
和__getitem__
,但如果你想更健壮的实现,让我知道):
import collections
class CountedOrderedDict(collections.OrderedDict):
def __init__(self, *args, **kwargs):
self.counter = collections.Counter()
super(CountedOrderedDict, self).__init__(*args, **kwargs)
def __delitem__(self, key):
super(CountedOrderedDict, self).__delitem__(key)
self.counter[key[1]] -= 1
def __setitem__(self, key, value):
if key not in self:
self.counter[key[1]] += 1
super(CountedOrderedDict, self).__setitem__(key, value)
实例:
>>> my_dict = CountedOrderedDict({(123,1): 'sda', (232,1) : 'bfd', (234,2) : 'csd', (6745,2) : 'ds', (456,3) : 'rd'})
>>> my_dict.counter
Counter({'1': 2, '2': 2, '3': 1})
>>> del my_dict[(123,1)]
>>> my_dict.counter
Counter({'2': 2, '1': 1, '3': 1})
>>> my_dict[(150,1)] = "asdf"
>>> my_dict.counter
Counter({'1': 2, '2': 2, '3': 1})
这里有一个更一般的CountedOrderedDict
实现,它需要一个关键的功能参数。
import collections
class CountedOrderedDict(collections.OrderedDict):
def __init__(self, key=lambda k: k, *args, **kwargs):
self.counter = collections.Counter()
self.key_transform = key
super(CountedOrderedDict, self).__init__(*args, **kwargs)
def __delitem__(self, key):
super(CountedOrderedDict, self).__delitem__(key)
self.counter[self.key_transform(key)] -= 1
def __setitem__(self, key, value):
if key not in self:
self.counter[self.key_transform(key)] += 1
super(CountedOrderedDict, self).__setitem__(key, value)
对于你的需求,你实例化它就像这样:
my_dict = CountedOrderedDict(key=lambda k: k[1])