【问题标题】:Sort string list by a number in string?按字符串中的数字对字符串列表进行排序?
【发布时间】:2018-07-02 23:31:48
【问题描述】:

我有以下字符串列表。然后,我想按每个元素中的数字对其进行排序。 sorted 失败,因为它无法处理 103 之间的订单。我可以想象如果我使用re,我可以做到。但这并不有趣。你们有很好的实施想法吗?我想这个代码是 python 3.x。

names = [
'Test-1.model',
'Test-4.model',
'Test-6.model',
'Test-8.model',
'Test-10.model',
'Test-20.model'
]
number_sorted = get_number_sorted(names)
print(number_sorted)
'Test-20.model'
'Test-10.model'
'Test-8.model'
'Test-6.model'
'Test-4.model'
'Test-1.model'

【问题讨论】:

    标签: python python-3.x string sorting


    【解决方案1】:

    关键是……关键

    sorted(names, key=lambda x: int(x.partition('-')[2].partition('.')[0]))
    

    通过将字符串的那部分分离出来并将其转换为 int 来将其识别为排序顺序。

    【讨论】:

      【解决方案2】:

      一些替代方案:

      (1) 按位置切片:

      sorted(names, key=lambda x: int(x[5:-6]))
      

      (2) 剥离子串:

      sorted(names, key=lambda x: int(x.replace('Test-', '').replace('.model', '')))
      

      (3) 分割字符(也可以通过str.partition):

      sorted(names, key=lambda x: int(x.split('-')[1].split('.')[0]))
      

      (4) 在 (1)-(3) 中的任何一个上使用 np.argsort 映射:

      list(map(names.__getitem__, np.argsort([int(x[5:-6]) for x in names])))
      

      【讨论】:

      • 鉴于目标是对原始字符串进行排序,而不仅仅是获得排序后的数字,使用key 函数执行转换会更有意义(并避免不必要的基因expr),例如对于你的第一个例子,sorted(names, key=lambda x: int(x[5:-6])),或者你的第二个例子sorted(names, key=lambda x: int(x.replace('Test-', '').replace('.model', '')))
      • @ShadowRanger,是的,我现在意识到了这一点。我已经编辑了我的答案。
      • 我现在喜欢多种选择。这是创新。
      【解决方案3】:

      我自己找到了一个类似的问题和解决方案。 Nonalphanumeric list order from os.listdir() in Python

      import re
      def sorted_alphanumeric(data):
          convert = lambda text: int(text) if text.isdigit() else text.lower()
          alphanum_key = lambda key: [ convert(c) for c in re.split('([0-9]+)', key) ] 
          return sorted(data, key=alphanum_key, reverse=True)
      

      【讨论】:

        【解决方案4】:

        您可以将re.findall 与排序功能的key 一起使用:

        import re
        names = [
         'Test-1.model',
         'Test-4.model',
         'Test-6.model',
         'Test-8.model',
         'Test-10.model',
         'Test-20.model'
        ]
        final_data = sorted(names, key=lambda x:int(re.findall('(?<=Test-)\d+', x)[0]), reverse=True)
        

        输出:

        ['Test-20.model', 'Test-10.model', 'Test-8.model', 'Test-6.model', 'Test-4.model', 'Test-1.model']
        

        【讨论】:

          【解决方案5】:
          def find_between( s, first, last ):
              try:
                  start = s.index( first ) + len( first )
                  end = s.index( last, start )
                  return s[start:end]
              except ValueError:
                  return ""
          

          然后做类似的事情

           sorted(names, key=lambda x: int(find_between(x, 'Test-', '.model')))
          

          【讨论】:

            【解决方案6】:

            假设每个字符串的格式相同,您可以使用key 参数和sorted() 来完成此操作:

            def get_number_sorted(somelist):
                return sorted(somelist, key=lambda x: int(x.split('.')[0].split('-')[1]))
            

            看起来您可能希望您的列表反向排序 (?),在这种情况下,您可以添加 reverse=True

            def get_number_sorted(somelist):
                return sorted(somelist, key=lambda x: int(x.split('.')[0].split('-')[1]), reverse=True)
            number_sorted = get_number_sorted(names)
            print(number_sorted)
            ['Test-20.model', 'Test-10.model', 'Test-8.model', 'Test-6.model', 'Test-4.model', 'Test-1.model']
            

            查看相关:Key Functions

            【讨论】:

              【解决方案7】:

              这是一种基于正则表达式的方法。我们可以从字符串中提取测试号,转换为int,然后按那个排序。

              import re
              
              def grp(txt): 
                  s = re.search(r'Test-(\d+)\.model', txt, re.IGNORECASE)
                  if s:
                      return int(s.group(1))
                  else:
                      return float('-inf')  # Sorts non-matching strings ahead of matching strings
              
              names.sort(key=grp)
              

              【讨论】:

              • 这仍然对字符串样式进行排序(按字典顺序),而不是按数字排序。在第一种情况下,您希望返回 int(s.group(1)),并在else 案例。
              • @ShadowRanger 不,即使making those changes 仍然无法修复它。顺便说一句,我不知道 Python。随意编辑。
              • @TimBiegeleisen: list.sort 在原地运行并返回 None(这意味着“没有返回值”)。您的测试代码通过分配names.sort 的结果将names 重新分配给None,这就是它中断的原因。我从names = names.sort(key=lambda l: grp(l)) 中删除了names = (并简化为names.sort(key=grp);不需要lambda 包装器,因为grp 已经有正确的原型)和it works fine
              猜你喜欢
              • 2021-06-10
              • 2014-07-30
              • 2012-04-03
              • 2022-11-25
              • 2017-08-11
              • 2014-02-21
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多