【问题标题】:How to Sort the dict by value in Python? [duplicate]如何在 Python 中按值对字典进行排序? [复制]
【发布时间】:2020-06-26 07:32:25
【问题描述】:

我只想按值对字典进行排序,但方式略有不同。

这是我的字典

issues = {
    1: {'title': 'Title 1','level': 'low'}, 
    2: {'title': 'Title 2','level': 'medium'}, 
    3: {'title': 'Title 3','level': 'high'}, 
    4: {'title': 'Title 4','level': 'low'}, 
    5: {'title': 'Title 5','level': 'medium'}, 
    6: {'title': 'Title 6','level': 'high'}
}

我想按级别(低、中、高)对上述问题进行排序。

sorted_issues = {
    1: {'title': 'Title 1','level': 'low'}, 
    4: {'title': 'Title 4','level': 'low'}, 
    2: {'title': 'Title 2','level': 'medium'}, 
    5: {'title': 'Title 5','level': 'medium'}, 
    3: {'title': 'Title 3','level': 'high'}, 
    6: {'title': 'Title 6','level': 'high'}
}

我有很多示例,但所有示例在 value 部分中只有一个值。 但是这里的值不是它的字典的单值

提前致谢。

【问题讨论】:

  • 对字典进行排序没有意义。如果您需要有序的数据结构,请使用其他东西
  • 这能回答你的问题吗? How do I sort a dictionary by value?
  • @MaO Python dicts 从 3.7 开始正式订购,从 3.6 开始非正式订购,显然 OrderedDict 已经存在很长时间了。

标签: python python-3.x sorting dictionary


【解决方案1】:

你可以这样做

from collections import OrderedDict
issues = {
    1: {'title': 'Title 1','level': 'low'},
    2: {'title': 'Title 2','level': 'medium'},
    3: {'title': 'Title 3','level': 'high'},
    4: {'title': 'Title 4','level': 'low'},
    5: {'title': 'Title 5','level': 'medium'},
    6: {'title': 'Title 6','level': 'high'}
}
priorities = {
    'low': 1,
    'medium': 2,
    'high': 3
}
x = OrderedDict(sorted(issues.items(), key = lambda item: priorities[item[1]['level']]))
for key, value in x.items():
    print(f"{key}, {value}")
'''
1, {'title': 'Title 1', 'level': 'low'}
4, {'title': 'Title 4', 'level': 'low'}
2, {'title': 'Title 2', 'level': 'medium'}
5, {'title': 'Title 5', 'level': 'medium'}
3, {'title': 'Title 3', 'level': 'high'}
6, {'title': 'Title 6', 'level': 'high'}
'''
print(x)
'''
OrderedDict([(1, {'title': 'Title 1', 'level': 'low'}), (4, {'title': 'Title 4', 'level': 'low'}), (2, {'title': 'Title 2', 'level': 'medium'}), (5, {'title': 'Title 5', 'level': 'medium'}), (3, {'title': 'Title 3', 'level': 'high'}), (6, {'title': 'Title 6', 'level': 'high'})])
'''

【讨论】:

    【解决方案2】:

    字典维护 python 的插入顺序3.7>,否则你有OrderedDict。要以这种方式对字典进行排序,您需要定义一个查找表来对级别字段进行排序,然后使用元组(level_lookup, title) 进行排序(假设您还需要按title 排序,否则只需要第一项)。

    另请注意,您需要将title 中的数字部分转换为整数,否则排序将按字典顺序排列,这意味着9 > 10

    mapper = {'low':0, 'medium':1, 'high':2}
    dict(sorted(issues.items(), key=lambda x: (mapper[x[1]['level']], 
                                               int(x[1]['title'].rsplit(maxsplit=1)[1]))))
    
    {1: {'title': 'Title 1', 'level': 'low'},
     4: {'title': 'Title 4', 'level': 'low'},
     2: {'title': 'Title 2', 'level': 'medium'},
     5: {'title': 'Title 5', 'level': 'medium'},
     3: {'title': 'Title 3', 'level': 'high'},
     6: {'title': 'Title 6', 'level': 'high'}}
    

    如果不需要通过title 进一步排序,您只需要:

    dict(sorted(issues.items(), key=lambda x: mapper[x[1]['level']]))
    

    【讨论】:

      【解决方案3】:

      即使不维护输入顺序,我们也可以编写一个自定义函数,用于根据提供的键或标签进行排序(在您的情况下为level),

      import pprint
      issues = {
          1: {'title': 'Title 1','level': 'low'}, 
          2: {'title': 'Title 2','level': 'medium'}, 
          3: {'title': 'Title 3','level': 'high'}, 
          4: {'title': 'Title 4','level': 'low'}, 
          5: {'title': 'Title 5','level': 'medium'}, 
          6: {'title': 'Title 6','level': 'high'}
      }
      
      def customSort(data, labels):
          temp = {}
          inx = 0
          for label in labels:
              for k,v in data.items():
                  if v["level"] == label:
                      inx += 1
                      temp[inx] = v.copy()
          return temp
      
      labels = ["low","medium","high"]
      issues_sorted = customSort(issues,labels)
      pprint.pprint(issues_sorted)
      

      输出:

      {1: {'level': 'low', 'title': 'Title 1'},
       2: {'level': 'low', 'title': 'Title 4'},
       3: {'level': 'medium', 'title': 'Title 2'},
       4: {'level': 'medium', 'title': 'Title 5'},
       5: {'level': 'high', 'title': 'Title 3'},
       6: {'level': 'high', 'title': 'Title 6'}}
      

      【讨论】:

        【解决方案4】:

        由于 Python 版本 3.7 dicts 保持元素的插入顺序。在以前的 python 版本中,情况并非如此。

        因此,您可以订购项目,根据您的标准对它们进行排序,然后将它们插入(新)字典中。

        或者使用OrderedDict:

        import collections
        
        def custom_sort(item):
            prio = ['low', 'medium', 'high']
            return prio.index(item[-1]["level"])
        
        issues = {
            1: {'title': 'Title 1','level': 'low'},
            2: {'title': 'Title 2','level': 'medium'},
            3: {'title': 'Title 3','level': 'high'},
            4: {'title': 'Title 4','level': 'low'},
            5: {'title': 'Title 5','level': 'medium'},
            6: {'title': 'Title 6','level': 'high'}
        }
        
        res = collections.OrderedDict(sorted(issues.items(), key=custom_sort))
        print(res)
        

        【讨论】:

          【解决方案5】:

          这有点小题大做,因为“low”、“medium”和“high”的最后一个字母具有相当无意的字母顺序。但是一个班轮也不少:

          sorted_issues = {k: v for k, v in  sorted(issues.items(), key=lambda kv: kv[1]['level'][-1], reverse=True)}
          

          【讨论】:

            【解决方案6】:

            你可以试试

            issues = {
                1: {'title': 'Title 1','level': 'low'},
                2: {'title': 'Title 2','level': 'medium'},
                3: {'title': 'Title 3','level': 'high'},
                4: {'title': 'Title 4','level': 'low'},
                5: {'title': 'Title 5','level': 'medium'},
                6: {'title': 'Title 6','level': 'high'}
            }
            
            levels_priorty = ['low', 'medium', 'high']
            res = dict(sorted(issues.items(), key=lambda x: [levels_priorty.index(x[1]['level']), int(x[1]['title'].replace("Title ", ""))]))
            print(res)
            

            输出

            {1: {'title': 'Title 1', 'level': 'low'}, 
            4: {'title': 'Title 4', 'level': 'low'}, 
            2: {'title': 'Title 2', 'level': 'medium'}, 
            5: {'title': 'Title 5', 'level': 'medium'}, 
            3: {'title': 'Title 3', 'level': 'high'}, 
            6: {'title': 'Title 6', 'level': 'high'}}
            

            【讨论】:

              【解决方案7】:

              请尝试以下代码:

              issues = {
                      1: {'title': 'Title 1','level': 'low'}, 
                      2: {'title': 'Title 2','level': 'medium'}, 
                      3: {'title': 'Title 3','level': 'high'}, 
                      4: {'title': 'Title 4','level': 'low'}, 
                      5: {'title': 'Title 5','level': 'medium'}, 
                      6: {'title': 'Title 6','level': 'high'}
                  }
              sortlist=['low','medium','high']
                  
              sorted_issues={k: v for k, v in sorted(issues.items(), key=lambda item: sortlist.index(item[1]['level']))}
              print(sorted_issues)
              

              输出:

              {1: {'title': 'Title 1', 'level': 'low'}, 
              4: {'title': 'Title 4', 'level': 'low'}, 
              2: {'title': 'Title 2', 'level': 'medium'}, 
              5: {'title': 'Title 5', 'level': 'medium'}, 
              3: {'title': 'Title 3', 'level': 'high'}, 
              6: {'title': 'Title 6', 'level': 'high'}}
              

              【讨论】:

                【解决方案8】:

                只需几行代码即可轻松实现此目标,而无需导入或安装其他模块。

                因为低于 python 3.1 的字典无法记住它们的顺序。 https://docs.python.org/3.1/whatsnew/3.1.html

                你可以像这样简单地订购这个字典:

                issues = {
                            1: {'title': 'Title 1','level': 'low'}, 
                            2: {'title': 'Title 2','level': 'medium'}, 
                            3: {'title': 'Title 3','level': 'high'}, 
                            4: {'title': 'Title 4','level': 'low'}, 
                            5: {'title': 'Title 5','level': 'medium'}, 
                            6: {'title': 'Title 6','level': 'high'}
                        }
                
                
                # CONVERT THE issues DICTIONARY INTO A LIST
                issues_list = [{k: v} for k, v in issues.items()]
                
                # A FUNCTION THAT SELECTS THE SORTING ELEMENT 
                level = lambda issue: issue.items()[0][1]['level']
                
                # WE USE THIS DICTIONARY TO CONVERT THE SORTING ELEMENT INTO A NUMBER
                levels = {'low':1, 'medium':2, 'high':3}
                
                # A FUNCTION THAT RETURNS A NUMBER TO BE SORTED BY THE SORT FUNCTION
                dict_element = lambda d: levels[level(d)]
                
                # NOW SORT THE LIST BASED ON LEVEL
                issues_list.sort(key=dict_element)
                
                # PRINT SORTED LIST
                for i in issues_list:
                    print i
                
                
                # RESULT
                # {1: {'level': 'low', 'title': 'Title 1'}}
                # {4: {'level': 'low', 'title': 'Title 4'}}
                # {2: {'level': 'medium', 'title': 'Title 2'}}
                # {5: {'level': 'medium', 'title': 'Title 5'}}
                # {3: {'level': 'high', 'title': 'Title 3'}}
                # {6: {'level': 'high', 'title': 'Title 6'}} 
                

                【讨论】:

                  猜你喜欢
                  • 2012-08-09
                  • 2021-06-28
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-08-11
                  • 1970-01-01
                  • 2019-08-10
                  • 2013-03-14
                  • 2020-08-03
                  相关资源
                  最近更新 更多