【问题标题】:Sorting dictionaries by largest values: class method按最大值对字典进行排序:类方法
【发布时间】:2014-03-06 09:12:15
【问题描述】:

我想对一个特定的字典进行排序并返回 top_n 出现次数的列表。字典是 txt 文档中单词的集合,“key”是 txt 文件中的单个单词,“value”是它在文档中出现的次数。

我的init方法如下:

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])

现在,我的一个实例方法将返回一个字符串列表,该列表的出现次数为“前 n”,给出了一些 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)

【问题讨论】:

  • 你只是需要这个来工作,还是你想找出方法来作为一个学习练习?有一个内置类可以更有效地为您执行此操作,collections.Counter
  • 不,我试图在没有 collections.Counter 帮助的情况下将此作为学习练习。

标签: python list sorting python-3.x dictionary


【解决方案1】:

我通过创建包含 dict_items 的变量“关联”解决了这个问题。例如:

associations = self.counts.items()

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

然后我在列表推导中使用了这个变量。我通过创建一个 lambda 函数并索引该对中的第二个元素,按降序(从大到小)对关联进行排序。出现次数最多的单词将位于列表中的索引 [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]]

【讨论】:

    【解决方案2】:
    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 已经完成了您需要的工作,并且使用线性时间而不是二次时间的计数算法。

    【讨论】:

    • 您也可以使用sorted(self.counts.items(), key=operator.itemgetter(1), reverse=True)。通常我会赞成这样做,但由于您只是在寻找密钥(在您的原始呼叫中为pair[0]),因此使用get 可能会更清楚。
    猜你喜欢
    • 1970-01-01
    • 2016-04-30
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    相关资源
    最近更新 更多