【问题标题】:How to sort a dictionary by key in python [duplicate]如何在python中按键对字典进行排序[重复]
【发布时间】:2015-11-03 06:25:39
【问题描述】:

我有一个名为data的python字典,里面有子字典,比如

data = {'ind1' : {}, 'ind10' : {}, 'ind11' : {}, 'ind12' : {}, 'ind13', 'ind14' : {}, 'ind15' : {}, 'ind16' : {}, 'ind17' : {}, 'ind18' : {}, 'ind19' : {}, 'ind2' : {}, 'ind20' : {}, 'ind3' : {}, 'ind30' : : {}, 'ind31' : {} 'ind5' : {}, 'ind6' : {}, 'ind7' : {}, 'ind8' : {}, 'ind9' : {}}

我想将字典中的数据按键排序为

ind1
ind2 : {}
ind3 : {}
...
ind10 : {}
ind11 : {}

我尝试了收藏库中的data = collections.OrderedDict(sorted(data.items()))

这是给出的结果

ind1 : {}
ind11 : {}
ind12 : {}
ind13 : {}
.....
ind20 : {}
ind21 : {}
....
ind3 : {}
ind4 : {}
....

请帮忙

【问题讨论】:

  • 你想先natural sort你的钥匙...
  • 为什么要对字典进行按键排序?也许这实际上并不是您需要做的事情。
  • 使用OrderedDict 可能是个坏主意,OrderedDicts 中的键按插入顺序排序,仅此而已。现在,如果您插入了 ind1ind3 并且排序良好,则您不能插入 ind2 并期望它不再被正确排序。
  • 谢谢,**natsort ** 做得最好,因为它也按字母顺序自然排序

标签: python python-2.7 sorting dictionary


【解决方案1】:

您需要以“ind”为前缀的键吗?您可以使用整数作为正确排序的键。现在它正在按字母顺序排序,这导致了问题。

如果你不能,假设你的键遵循相同的格式,使用这个排序:

 collections.OrderedDict(sorted(data.items(), key=lambda kv: int(kv[0][3:])))

其中使用前缀后面的整数进行排序。

【讨论】:

  • 没有键是一些文件名,可能有另一个前缀说 foo1, bar2... 或者只有 foo, bar 等。
  • 这段代码可以很好地解决您的问题。您可能更喜欢通过解释一些极端情况来编辑您的问题。
  • @KangkonSaikia,您应该在示例中始终使用真实数据(或尽可能接近真实数据):)。如果键是文件名,那么要么使用那些确切的文件名,要么至少使用代表真实数据多样性的文件名。
【解决方案2】:

您真的要对内部字典中的数据进行排序,还是只想对 .keys() 提供的列表进行排序?

如果您只对值列表进行排序,则此链接应包含您需要的内容:https://wiki.python.org/moin/HowTo/Sorting

如果您想对字典中的数据进行排序,我很想知道为什么。我会在您回复时关注并添加建议。

祝你好运!

【讨论】:

    【解决方案3】:

    如果您希望“ind10”在“ind9”之后,则需要对键使用自然排序算法;^)

    来自ActiveState上的wizkid

    def keynat(string):
      r'''A natural sort helper function for sort() and sorted()
      without using regular expression.
    
      >>> items = ('Z', 'a', '10', '1', '9')
      >>> sorted(items)
      ['1', '10', '9', 'Z', 'a']
      >>> sorted(items, key=keynat)
      ['1', '9', '10', 'Z', 'a']
      '''
      r = []
      for c in string:
         if c.isdigit():
            if r and isinstance(r[-1], int):
               r[-1] = r[-1] * 10 + int(c)
            else:
               r.append(int(c))
         else:
            r.append(c)
      return r
    
    data = collections.OrderedDict(
      sorted(
        data.iteritems(),
        key=lambda row:keynat(row[0])
      )
    )
    

    【讨论】:

      【解决方案4】:

      如果您不需要每个键都以'ind' 开头,那么它们都可以是int,这将按预期工作。

      如果它们确实需要以'ind' 开头的字符串,您可以这样做:

      from __future__ import print_function
      
      import pprint
      
      from collections import OrderedDict
      
      
      def ind_sort_key(item):
          item_key, item_value = item
          return int(item_key[3:])
      
      
      data = {
          'ind1': {}, 'ind10': {}, 'ind11': {}, 'ind12': {}, 'ind13': {},
          'ind14': {}, 'ind15': {}, 'ind16': {}, 'ind17': {}, 'ind18': {},
          'ind19': {}, 'ind2': {}, 'ind20': {}, 'ind3': {}, 'ind30': {},
          'ind31': {}, 'ind5': {}, 'ind6': {}, 'ind7': {}, 'ind8': {}, 'ind9': {},
          }
      
      sorted_data = OrderedDict(sorted(data.items(), key=ind_sort_key))
      
      pprint.pprint(sorted_data)
      

      这会导致:

      {'ind1': {},
       'ind2': {},
       'ind3': {},
       'ind5': {},
       'ind6': {},
       'ind7': {},
       'ind8': {},
       'ind9': {},
       'ind10': {},
       'ind11': {},
       'ind12': {},
       'ind13': {},
       'ind14': {},
       'ind15': {},
       'ind16': {},
       'ind17': {},
       'ind18': {},
       'ind19': {},
       'ind20': {},
       'ind30': {},
       'ind31': {}}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-06-28
        • 2010-10-09
        • 2011-06-06
        • 2020-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多