2015-05-20 4 views
1

Я пытаюсь использовать OrderedDict() для отслеживания экземпляров слова. У меня есть данные, которые организованы днем, и я хочу подсчитать количество экземпляров «foo» в этот день. Каждая строка индексируется по дням. Использование defaultdict дает мне то, что я хочу, но, конечно, без заказа:Использование OrderedDict для подсчета экземпляров

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) 

ответ

0

Вы можете определить свой собственный класс, который наследует от обоих defaultdict и OrderedDict.

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

counter = OrderedDefaultDict(int) 
+0

Я бы не рекомендовал это. Ни 'defaultdict', ни' OrderedDict' не были предназначены для использования с множественным наследованием. Я вижу, что вы пытались решить проблемы с несколькими инициализациями, но они все еще намного хрупкие, чем просто наследование от 'OrderedDict' и предоставление собственного метода' __missing__'. – user2357112

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 и использовать это как ключ в своем defaultdict. Затем вы можете сортировать по клавишам и получать все элементы по порядку по дате/времени - независимо от того, какой порядок они отображаются в исходном текстовом файле.


Как @ 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 
+0

Или 'counter [day] = counter.get (день, 0) + 1'. – user2357112

+0

@ user2357112 пригвоздил его! – superhero

+0

Хороший звонок @ user2357112. Не уверен, почему я не думал, что так делаю сам. Я обновил ответ и дал вам кредит. – Waylan

Смежные вопросы