【问题标题】:Using OrderedDict to count instances使用 OrderedDict 统计实例
【发布时间】:2015-05-20 19:14:08
【问题描述】:

我正在尝试使用 OrderedDict() 来跟踪单词的实例。我有按天组织的数据,我想计算当天“foo”实例的数量。每条线都按天索引。使用 defaultdict 给了我我想要的东西,但是,当然,没有排序:

from collections import defaultdict
counter = defaultdict(int)

w = open('file.txt', 'r')
y = w.readlines()
for line in y:
    day,words = line[:6], line[14:]
    if re.search(r"foo", words):
        counter[day] += 1

如果我使用 OrderedDict,我该如何做同样的事情,以便按照读取的方式对数据进行排序?如果我使用

for key, value in sorted(counter.items()):
    print(key, value)

然后我按字母顺序获取列表。我知道我可以将日期读入一个数组,然后基于此迭代键,但是,这似乎非常低效。

假设我的文本文件如下所示:

Sep 1, 2014, 22:23 - ######: Here is a foo
Sep 1, 2014, 22:23 - ######: Not here
Sep 2, 2014, 19:09 - ######: foo sure
Sep 2, 2014, 19:57 - ######: footastic
Sep 2, 2014, 19:57 - ######: foo-king awesome
Sep 2, 2014, 19:57 - ######: No esta aqui

我想打印我的字典:

('Sep 1,', 1)
('Sep 2,', 3)

【问题讨论】:

    标签: python counter ordereddictionary


    【解决方案1】:

    您可以检查 day 是否在 OrderedDict 中。如果有,添加它,如果没有设置为1

    counter = OrderedDict()
    
    w = open('file.txt', 'r')
    y = w.readlines()
    for line in y:
        day,words = line[:6], line[14:]
        if re.search(r"foo", words):
            if day in counter:
                counter[day] += 1
            else:
                counter[day] = 1
    

    当然,OrderedDict 将按每天在源文本文件中的第一次出现进行排序。

    相反,您可以考虑将日期解析为 datetime.date 对象并将其用作默认字典的键。然后,您可以对键进行排序并按日期/时间按顺序获取所有项目 - 无论它们在源文本文件中出现的顺序如何。


    正如@user2357112 在评论中指出的那样,您可以在增加计数器时使逻辑更简单。像这样:

    counter = OrderedDict()
    
    w = open('file.txt', 'r')
    y = w.readlines()
    for line in y:
        day,words = line[:6], line[14:]
        if re.search(r"foo", words):
            counter[day] = counter.get(day, 0) + 1
    

    【讨论】:

    • counter[day] = counter.get(day, 0) + 1
    • @user2357112 成功了!
    • 很好的电话@user2357112。不知道为什么我自己不这么想。我已经更新了答案并给了你信用。
    【解决方案2】:

    您可以定义自己的类,该类继承自 defaultdictOrderedDict

    class OrderedDefaultDict(defaultdict, OrderedDict):
        def __init__(self, default, *args, **kwargs):
            defaultdict.__init__(self, default)
            OrderedDict.__init__(self, *args, **kwargs)
    
    counter = OrderedDefaultDict(int)
    

    【讨论】:

    • 我不推荐这个。 defaultdictOrderedDict 都不是设计用于多继承的。我看到你试图解决多重初始化的问题,但它仍然比仅仅从 OrderedDict 继承并提供你自己的 __missing__ 方法要脆弱得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-27
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 2017-01-27
    • 1970-01-01
    相关资源
    最近更新 更多