python - 从 OrderedDict 获取键计数,其中键是一个元组

标签 python python-2.7 counter ordereddictionary

我有一本这样的字典:

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 函数,以便它添加或减去我每次执行该操作都会计数吗?

最佳答案

CounterOrderedDict 很好地配合工作可能需要一些子类化。下面是一些可能有效的方法(我只实现了 __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])

关于python - 从 OrderedDict 获取键计数,其中键是一个元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25555279/

相关文章:

python - 创建 3D 圆锥体或圆盘并使用 matplotlib 不断更新其对称轴

python - 在 Python 2.7 中导入 urllib 或 urllib 2 失败,出现 ImportError : cannot import name iskeyword

python - 计算列表中某个元素的出现次数

c# - 如何将计数添加到 Winform 中的按钮单击

python - 为什么 apt-get 功能在 Mac OS X v10.9 (Mavericks) 的终端中不起作用?

python - 使用 tf.reduce_mean 与 tf.concat 进行灰度转换

python - 仅从 App Engine 中的 ReferenceProperty 获取 Key/id

python - 如何在 pandas groupby 中包含零交叉项?

python - 使用spark-submit和BeautifulSoup时出现UnicodeEncodeError

database - VB.Net - 每次在数据库中创建新行时计数+1