【问题标题】:Sorting a list of strings with numbers in them in python在python中对带有数字的字符串列表进行排序
【发布时间】:2017-09-15 00:48:56
【问题描述】:

所以我有一个字符串路径列表:

x = ['../../scene/temp_5a/458754/1_car.png',
     '../../scene/temp_5a/458754/2_car.png',
     '../../scene/temp_5a/458754/10_car.png',
     '../../scene/temp_5a/458754/15_car.png',
     '../../scene/temp_5a/458754/3_car.png']

而且我需要按_car 前面的数字对其进行排序。有谁知道快速的方法吗?

我目前有这个,但似乎拆分正在获取所有数字。我只想得到_car前面的数字。

def atoi(text):
    return int(text) if text.isdigit() else text

def natural_keys(text):
    return [ atoi(c) for c in re.split('(\d+)', text) ]

x.sort(key=natural_keys) # gives an error

【问题讨论】:

  • 最后一行给你的错误是什么?我运行了你的代码,得到了你想要的排序输出,没有错误。
  • 你是对的!我忘记了 x.sort() 对数组进行排序,所以它输出 None 并导致我的部分代码吐出垃圾。谢谢!
  • 啊,是的,我知道那种感觉!很高兴听到你想通了,很高兴能提供帮助。干杯!

标签: python string list sorting


【解决方案1】:

我不确定你的正则表达式为什么给你一个错误,它对我有用。也许尝试不同的正则表达式?

r'.*\/([^_]*)_.*' 替换你的也可以:

x = ['../../scene/temp_5a/458754/1_car.png',
'../../scene/temp_5a/458754/2_car.png',
'../../scene/temp_5a/458754/10_car.png',
'../../scene/temp_5a/458754/15_car.png',
'../../scene/temp_5a/458754/3_car.png']

def atoi(text):
return int(text) if text.isdigit() else text

def natural_keys(text):
    return [ atoi(c) for c in re.split(r'.*\/([^_]*)_.*', text) ]

x.sort(key=natural_keys)
print x

输出:

['../../scene/temp_5a/458754/1_car.png',  
'../../scene/temp_5a/458754/2_car.png', 
'../../scene/temp_5a/458754/3_car.png', 
'../../scene/temp_5a/458754/10_car.png', 
'../../scene/temp_5a/458754/15_car.png']

【讨论】:

    【解决方案2】:

    我的方法是拆分字符串,用_car前面的数字作为key进行比较。

    >>> x = [
    ...     '../../scene/temp_5a/458754/1_car.png',
    ...     '../../scene/temp_5a/458754/2_car.png',
    ...     '../../scene/temp_5a/458754/10_car.png',
    ...     '../../scene/temp_5a/458754/15_car.png',
    ...     '../../scene/temp_5a/458754/3_car.png']
    >>>
    >>> sorted(x,key=lambda i: int(i.split('/')[-1].split('_')[0]))
    [[1, '../../scene/temp_5a/458754/1_car.png'], [2, '../../scene/temp_5a/458754/2_car.png'], [3, '../../scene/temp_5a/458754/3_car.png'], [10, '../../scene/temp_5a/458754/10_car.png'], [15, '../../scene/temp_5a/458754/15_car.png']]
    

    【讨论】:

      【解决方案3】:
      x = ['../../scene/temp_5a/458754/1_car.png',
      '../../scene/temp_5a/458754/2_car.png',
      '../../scene/temp_5a/458754/10_car.png',
      '../../scene/temp_5a/458754/15_car.png',
      '../../scene/temp_5a/458754/3_car.png']
      sorted(x,key=lambda x: int(x.split('/')[-1].split('_car')[0]))
      
      Out[118]: 
      ['../../scene/temp_5a/458754/1_car.png',
       '../../scene/temp_5a/458754/2_car.png',
       '../../scene/temp_5a/458754/3_car.png',
       '../../scene/temp_5a/458754/10_car.png',
       '../../scene/temp_5a/458754/15_car.png']
      

      【讨论】:

        【解决方案4】:

        字符串匹配是正则表达式的作用。只需要很少的正则表达式。

        import re
        
        x = ['../../scene/temp_5a/458754/1_car.png',
             '../../scene/temp_5a/458754/2_car.png',
             '../../scene/temp_5a/458754/10_car.png',
             '../../scene/temp_5a/458754/15_car.png',
             '../../scene/temp_5a/458754/3_car.png']
        
        
        def file_matcher(files):
            numbers = []
            for f in files:
                match = re.search(r'([0-9]+)_car.png', f)
                numbers.append(match.group(1))
            return numbers
        
        print file_matcher(x)
        

        【讨论】:

          猜你喜欢
          • 2016-09-13
          • 1970-01-01
          • 1970-01-01
          • 2016-05-10
          • 1970-01-01
          • 2013-07-02
          相关资源
          最近更新 更多