【问题标题】:Sorted function in Python dictionaryPython字典中的排序函数
【发布时间】:2022-11-25 17:01:24
【问题描述】:

我有一本字典,我需要打印字典的内容,首先按“值”排序,如果有任何价值关系,那么我需要使用“键”作为决胜局,以便打印具有相同值的键字母顺序。

final = OrderedDict(sorted(mydict.items(), key=lambda x: (x[1], x[0]), reverse=True))

for key, value in final.items():
    print(f'{key} : {value}')

但是当打印命令运行时,它会显示相同的值没有按预期排序的输出:

Action : 3
Romance : 2
Horror : 2
History : 2
Comedy : 2
Adventure : 1

它应该打印的方式必须是这样的:

Action : 3
Comedy : 2
History : 2
Horror : 2
Romance : 2
Adventure : 1

关于如何纠正此问题的任何想法?

【问题讨论】:

  • 您使用了reverse=True,所以决胜局也是反向排序的。
  • 您可以使用负数技巧并使用key=lambda x: (-x[1], x[0]) 而不是使用reverse=True
  • 正如@chepner 所提到的,问题是您的期望,因此要纠正此问题只需改变您的期望。
  • 这回答了你的问题了吗? Python sorting by multiple criteria

标签: python dictionary


【解决方案1】:

您只想反转 x[1] 的排序,所以不要在此处传递 reverse=True,而是使用负数技巧:

final = OrderedDict(sorted(mydict.items(), key=lambda x: (-x[1], x[0])))

【讨论】:

    【解决方案2】:
    {k: v for k, v in sorted(mydict.items(), key=lambda item: (-item[1], item[0]), reverse=False)}
    

    【讨论】:

    • 一个不必要的复杂解决方案。请参阅问题下 chepner 的评论。
    • @JeffreyRam 这正是我所指的; reverse 参数可以简单地删除而不是显式传递 False
    • {k: v for k, v in }reverse=False 是不必要的。
    • 如果您不调用dict,则必须进行字典理解(尽管将排序列表传递给dict更简单).
    • @JeffreyRam imo 使用内置功能在代码的可重现性和优化/性能方面尽可能好。
    【解决方案3】:

    reverse已申请序列已根据key 排序。您只想反转 x[1] 上的比较,而不是最终排序。我会使用 functools.cmp_to_key 将比较函数转换为键函数。

    from functools import cmp_to_key
    
    # Redefined from Python 2 since Python 3 dropped it
    def cmp(x, y):
        return -1 if x < y else 0 if x == y else 1
    
    def genre_sort(x, y):
        # A bigger count is a smaller genre; otherwise, sort alphabetically
        # by name
        return cmp(y[1], x[1]) or cmp(x[0], y[0])
        
    final = OrderedDict(sorted(mydict.items(), key=cmp_to_key(genre_sort)))
    

    【讨论】:

      【解决方案4】:

      为什么这个答案已经有其他三个?

      在我看来,其他答案都没有揭示问题中描述的问题的核心,顺便说一下,已经充分回答了here: https://stackoverflow.com/questions/20145842/python-sorting-by-multiple-criteriahere https://stackoverflow.com/questions/55866762/how-to-sort-a-list-of-strings-in-reverse-order-without-using-reverse-true-parame 使其成为作为副本关闭的候选者。

      Python 的特性允许解决以不同排序顺序对列进行排序的问题是这样的事实

      Python 的排序是稳定的 允许您使用连续排序,首先使用最右边的标准,然后使用下一个,等等。(Martijn Pieters).

      Python 的排序算法是稳定的,这意味着相等的元素保持它们的相对顺序。因此,您可以对第二个元素使用第一个排序(按升序排序),然后再次排序,仅对第一个元素按相反的顺序排序。

      我已将问题中列出的字典更改为仅包含字符串值,这将不允许在键函数中使用带有负数值的“技巧”来获得所需的结果来演示上面所说的内容。

      下面的代码:

      mydict = { 
          'Romance'   : '2', 
          'Adventure' : '1', 
          'Action'    : '3', 
          'Horror'    : '2', 
          'History'   : '2',
          'Comedy'    : '2',
      }
      mylist = list(mydict.items())
      print(mylist)
      print()
      mylist = sorted(mylist)
      print(mylist)
      mslist = sorted(mylist, key=lambda x: (x[1]), reverse=True)
      print(mslist)
      from collections import OrderedDict
      final = OrderedDict(mslist)
      for key, value in final.items():
          print(f'  {key:10} : {value}')
      

      创建以下输出:

      [('Romance', '2'), ('Adventure', '1'), ('Action', '3'), ('Horror', '2'), ('History', '2'), ('Comedy', '2')]
      
      [('Action', '3'), ('Adventure', '1'), ('Comedy', '2'), ('History', '2'), ('Horror', '2'), ('Romance', '2')]
      [('Action', '3'), ('Comedy', '2'), ('History', '2'), ('Horror', '2'), ('Romance', '2'), ('Adventure', '1')]
        Action     : 3
        Comedy     : 2
        History    : 2
        Horror     : 2
        Romance    : 2
        Adventure  : 1
      

      演示我在这里谈论的内容。

      从:

      [('Action', '3'), ('Adventure', '1'), ('Comedy', '2'), ('History', '2'), ('Horror', '2'), ('Romance', '2')]
      [('Action', '3'), ('Comedy', '2'), ('History', '2'), ('Horror', '2'), ('Romance', '2'), ('Adventure', '1')]
      

      可以看出,第二种排序仅移动'('Adventure', '1')',保持所有其他项目的顺序。

      【讨论】:

        猜你喜欢
        • 2013-05-01
        • 2011-05-18
        • 2017-02-18
        • 1970-01-01
        • 2011-01-25
        • 2017-01-23
        • 1970-01-01
        • 2011-08-28
        • 1970-01-01
        相关资源
        最近更新 更多