【问题标题】:How to sort Counter by value? - python如何按值对计数器进行排序? - Python
【发布时间】:2014-01-23 21:32:03
【问题描述】:

除了对反向列表推导进行列表推导之外,是否有一种 Pythonic 方法可以按值对 Counter 进行排序?如果是这样,它比这更快:

>>> from collections import Counter
>>> x = Counter({'a':5, 'b':3, 'c':7})
>>> sorted(x)
['a', 'b', 'c']
>>> sorted(x.items())
[('a', 5), ('b', 3), ('c', 7)]
>>> [(l,k) for k,l in sorted([(j,i) for i,j in x.items()])]
[('b', 3), ('a', 5), ('c', 7)]
>>> [(l,k) for k,l in sorted([(j,i) for i,j in x.items()], reverse=True)]
[('c', 7), ('a', 5), ('b', 3)

【问题讨论】:

    标签: python sorting collections counter


    【解决方案1】:

    使用Counter.most_common() method,它会为您对项目进行排序

    >>> from collections import Counter
    >>> x = Counter({'a':5, 'b':3, 'c':7})
    >>> x.most_common()
    [('c', 7), ('a', 5), ('b', 3)]
    

    它将以最有效的方式进行;如果您要求 Top N 而不是所有值,则使用 heapq 而不是直接排序:

    >>> x.most_common(1)
    [('c', 7)]
    

    在计数器之外,排序总是可以基于key函数进行调整; .sort()sorted() 都采用可调用对象,可让您指定对输入序列进行排序的值; sorted(x, key=x.get, reverse=True) 会给你与x.most_common() 相同的排序,但只返回键,例如:

    >>> sorted(x, key=x.get, reverse=True)
    ['c', 'a', 'b']
    

    或者您可以仅对给定的值进行排序 (key, value) 对:

    >>> sorted(x.items(), key=lambda pair: pair[1], reverse=True)
    [('c', 7), ('a', 5), ('b', 3)]
    

    请参阅Python sorting howto 了解更多信息。

    【讨论】:

      【解决方案2】:

      @MartijnPieters 的一个很好的补充是返回一个按出现次数排序的字典,因为Collections.most_common 只返回一个元组。我经常将此与方便的日志文件的 json 输出相结合:

      from collections import Counter, OrderedDict
      
      x = Counter({'a':5, 'b':3, 'c':7})
      y = OrderedDict(x.most_common())
      

      输出:

      OrderedDict([('c', 7), ('a', 5), ('b', 3)])
      {
        "c": 7, 
        "a": 5, 
        "b": 3
      }
      

      【讨论】:

      • 从 Python 3.7(CPython 为 3.6)开始,不再需要 OrderedDict,因为 dict 现在保持插入顺序。所以它只是y = dict(x.most_common())
      【解决方案3】:

      是的:

      >>> from collections import Counter
      >>> x = Counter({'a':5, 'b':3, 'c':7})
      

      使用排序的关键字键和 lambda 函数:

      >>> sorted(x.items(), key=lambda i: i[1])
      [('b', 3), ('a', 5), ('c', 7)]
      >>> sorted(x.items(), key=lambda i: i[1], reverse=True)
      [('c', 7), ('a', 5), ('b', 3)]
      

      这适用于所有字典。但是Counter 有一个特殊的功能,它已经为您提供了排序的项目(从最频繁到最不频繁)。它叫most_common()

      >>> x.most_common()
      [('c', 7), ('a', 5), ('b', 3)]
      >>> list(reversed(x.most_common()))  # in order of least to most
      [('b', 3), ('a', 5), ('c', 7)]
      

      您还可以指定要查看的项目数量:

      >>> x.most_common(2)  # specify number you want
      [('c', 7), ('a', 5)]
      

      【讨论】:

      • 反向排序的另一种方法是将key函数设置为lamda i: -i[1]
      • 我忘记了.items(),然后它给了我TypeError: bad operand type for unary -: 'str'。只是您需要items() 将其读取为一对,以便找到k[1] 作为每对的第二项,可以使用-k[1] 反向排序,因为它是一个数字。您将无法执行 -k[0],因为 k[0] 是一个字符串。
      【解决方案4】:

      更一般的排序,其中key关键字定义排序方式,数字类型前的减号表示降序:

      >>> x = Counter({'a':5, 'b':3, 'c':7})
      >>> sorted(x.items(), key=lambda k: -k[1])  # Ascending
      [('c', 7), ('a', 5), ('b', 3)]
      

      【讨论】:

      • key关键字定义排序方式,数字类型前减号表示降序
      猜你喜欢
      • 1970-01-01
      • 2013-07-29
      • 2022-01-13
      • 1970-01-01
      • 2018-12-22
      • 2022-11-02
      • 1970-01-01
      • 2011-03-25
      • 2021-11-21
      相关资源
      最近更新 更多