【问题标题】:Sorting a List of List in Python by frequency在 Python 中按频率对列表进行排序
【发布时间】:2014-05-20 14:29:16
【问题描述】:

我正在尝试按出现频率对 Python 中的列表项列表进行排序 未排序的列表看起来像这样:

a=[     ['item1', 'item2', 'element2'],
        ['item3', 'item4', 'element3'],
        ['item5', 'item6', 'element1'],
        ['item7', 'item8', 'element3']]

我想按列表中第三个元素的频率排序。所以,排序后的结果列表会是这样的:

result = [  ['item3', 'item4', 'element3'],
            ['item7', 'item8', 'element3'],
            ['item1', 'item2', 'element2'],
            ['item5', 'item6', 'element1']]

我不是 Python 专家。有什么想法,怎么做?

【问题讨论】:

    标签: python list sorting


    【解决方案1】:

    您必须先收集频率; collections.Counter() object 会很好地做到这一点。然后,您可以查找频率并按以下顺序排序:

    from collections import Counter
    
    freq = Counter(item[-1] for item in a)
    result = sorted(a, key=lambda i: freq[i[-1]], reverse=True)
    

    这里freq 保存每个嵌套列表中最后一个元素的计数,然后我们使用一个排序键,以相反的顺序(最常见的排序在前)。

    演示:

    >>> from collections import Counter
    >>> a=[     ['item1', 'item2', 'element2'],
    ...         ['item3', 'item4', 'element3'],
    ...         ['item5', 'item6', 'element1'],
    ...         ['item7', 'item8', 'element3']]
    >>> freq = Counter(item[-1] for item in a)
    >>> sorted(a, key=lambda i: freq[i[-1]], reverse=True)
    [['item3', 'item4', 'element3'], ['item7', 'item8', 'element3'], ['item1', 'item2', 'element2'], ['item5', 'item6', 'element1']]
    >>> from pprint import pprint
    >>> pprint(_)
    [['item3', 'item4', 'element3'],
     ['item7', 'item8', 'element3'],
     ['item1', 'item2', 'element2'],
     ['item5', 'item6', 'element1']]
    

    【讨论】:

    • 我可以使用 operator.itemgetter 而不是 lamba 表达式来实现吗?
    • @iamdeowanshi 不,这使用嵌套索引,itemgetter() 实例无法在此处获得相同的结果。
    • 如果我们使用普通的嵌套列表,可以使用 itemgetter,那么为什么不按频率对嵌套列表进行排序
    • @iamdeowanshi:那是因为itemgetter(value) 对象本质上与lambda item: item[value] 相同。这里的 lambda 与那个 不同
    • @iamdeowanshi:i[-1] 是被排序事物的最后一个元素。 freq[...]Counter() 映射中的查找,因此将元素映射到它们的频率。因此,对于每个排序的['itemN', 'itemO', 'itemP]` 列表,查找'itemP' 的频率并返回以进行排序。
    【解决方案2】:

    看看collections.Counter

    例子:

    wordlist = ['foo', 'bar', 'foo', 'baz']
    import collections
    counter = collections.Counter(wordlist)
    counter.most_common()
    

    返回:

    [('foo', 2), ('baz', 1), ('bar', 1)]
    

    【讨论】:

      【解决方案3】:

      我认为没有必要导入 Counter 或其他任何东西,只需定义您自己的键函数,它将只返回列表的最后一个元素,以便根据该元素进行排序...

      因此,您可以将 'sorted' 与键函数 last_element(您定义的)一起使用,如下所示:

      def last_element(x): return x[-1]
      
      sorted(a, key=last_element, reverse=True)
      

      你会得到:

      [['item3', 'item4', 'element3'], ['item7', 'item8', 'element3'], ['item1', 'item2', 'element2'], ['item5', 'item6', 'element1']]
      

      如果您不想定义新函数,可以使用 lambda(类似于另一个答案中所示),因此只需一行的解决方案是:

      sorted(a, key=lambda x: x[-1], reverse=True)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-01-20
        • 1970-01-01
        • 1970-01-01
        • 2021-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-19
        相关资源
        最近更新 更多