2014-02-09 2 views
0

Я хочу сортировать определенный словарь и возвращать список top_n числа вхождений. Словарь представляет собой набор слов из документа txt, причем «ключ» - это одно слово из файла txt, а «значение» - его количество вхождений в документе.Сортировка словарей по наибольшим значениям: метод класса

У меня есть инициализации метод следующим образом:

def __init__(self:'Collection_of_words', file_name: str) -> None: 
    ''' this initializer will read in the words from the file, 
    and store them in self.counts''' 
    l_words = open(file_name).read().split() 
    s_words = set(l_words) 
    self.counts = dict([ [word, l_words.count(word)] 
         for word 
         in s_words]) 

Теперь один из моих методов экземпляра возвращает список строк в «сверху» п число вхождений Givin некоторые Int аргумент. Я дал ему шанс:

def top_n_words(self, i): 
    '''takes one additional parameter, an int, 
    <i> which is the top number of occurences. Returns a list of the top <i> words.''' 


    return [ pair[0] 
      for pair 
      in sorted(associations, key=lambda pair: pair[1], reverse=True)[:5]] 

Однако всякий раз, когда я запускаю этот код я получаю ошибки и не могу понять, почему. Я не уверен, как сортировать объекты словаря (например. Self.counts)

+3

Вам просто нужно это работать, или вы пытаетесь выяснить, как это сделать в качестве учебного упражнения? Есть встроенный класс, который сделает это для вас более эффективным способом, 'collections.Counter'. –

+0

Нет, я пытаюсь понять это как учебное упражнение с помощью коллекций. Каунтер. –

ответ

3
sorted(self.counts, key=lambda pair: pair[1], reverse=True) 

Перебор self.counts дает ключи, а не пар ключ-значение. Это означает, что pair[1] не будет работать. Вы хотите key=self.counts.get.

Если список должен включать счетчики, а также ключи, вам нужно вместо сортировки пар ключ-значение по значениям:

sorted(self.counts.items(), key=operator.itemgetter(1), reverse=True) 

Кроме того, обратите внимание, что collections.Counter уже делает то, что вам нужно, и с алгоритмом подсчета в линейном времени вместо квадратичного.

+0

Вы также можете использовать 'sorted (self.counts.items(), key = operator.itemgetter (1), reverse = True)'. Обычно я одобряю это, но поскольку вы ищете ключи ('pair [0]' в вашем исходном вызове, использование 'get' может быть более четким. –

0

Я решил это, создав переменные «ассоциации», содержащие dict_items. e.x .:

associations = self.counts.items() 

>>> associations 
>>>dict_items([('would,', 1), ('Even', 1), ('Cries', 1), ('Sings', 5)]) 

Затем я использовал эту переменную в понимании списка. Я сортировал ассоциации в порядке убывания (от самого большого до наименьшего), создавая лямбда-функцию и индексируя второй элемент в паре. Слово с наибольшим количеством вхождений будет иметь индекс [0] в списке.

def top_n_words(self, i): 

    associations = self.counts.items() 

     return [ pair[0] 
      for pair 
      in sorted(associations, key=lambda pair: pair[1], reverse=True)[:i]] 
Смежные вопросы