【问题标题】:Sort list of string based on number in string [duplicate]根据字符串中的数字对字符串列表进行排序[重复]
【发布时间】:2016-03-28 09:47:30
【问题描述】:

例如我有列表

my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg']

my_list.sort()

给我

['image1.jpg', 'image101.jpg', 'image2.jpg']

但我当然需要

['image1.jpg', 'image2.jpg', 'image101.jpg']

如何实现?

【问题讨论】:

  • sorted(my_list, key=lambda x: int(re.search(r'\d+(?=\.)', x).group()))

标签: python list sorting


【解决方案1】:

list.sort 接受可选的key 函数。每个项目都传递给函数,函数的返回值用于比较项目而不是原始值。

>>> my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg']
>>> my_list.sort(key=lambda x: int(''.join(filter(str.isdigit, x))))
>>> my_list
['image1.jpg', 'image2.jpg', 'image101.jpg']

filterstr.isdigit 用于提取数字:

>>> ''.join(filter(str.isdigit, 'image101.jpg'))
'101'
>>> int(''.join(filter(str.isdigit, 'image101.jpg')))
101
  • ''.join(..) 在 Python 2.x 中不是必需的

【讨论】:

  • 只是想提一下,如果文件名类似于image21_20160328.jpg,它将不起作用。它将提取的数字是2120160328
  • @JasonEstibeiro,你是对的。在这种情况下,需要捕获所有数字并转换它们,使用类似lits(map(int, re.findall(r'\d+', x)))
【解决方案2】:

使用正则表达式从字符串中提取数字并转换为 int:

import  re
r = re.compile("\d+")
l = my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg']
l.sort(key=lambda x: int(r.search(x).group()))

或者也许使用更具体的正则表达式,包括.

import  re

r = re.compile("(\d+)\.")
l = my_list= ['image101.jpg', 'image2.jpg', 'image1.jpg']
l.sort(key=lambda x: int(r.search(x).group()))

两者都为您的示例输入提供相同的输出:

['image1.jpg', 'image2.jpg', 'image101.jpg']

如果您确定扩展名,您可以使用非常具体的正则表达式:

 r = re.compile("(\d+)\.jpg$")
 l.sort(key=lambda x: int(r.search(x).group(1)))

【讨论】:

  • 为了准确,您必须使用前瞻。
  • 您需要将匹配的字符串转换为数字。否则,结果与 OP 想要的不同。 ['image1.jpg', 'image101.jpg', 'image2.jpg'] != ['image1.jpg', 'image2.jpg', 'image101.jpg']
  • @falsetru,是的,最初发布了错误的版本
【解决方案3】:

如果你想在一般情况下这样做,我会尝试像natsort这样的自然排序包。

from natsort import natsorted
my_list = ['image101.jpg', 'image2.jpg', 'image1.jpg']
natsorted(my_list)

返回:

['image1.jpg', 'image2.jpg', 'image101.jpg']

您可以使用 pip 安装它,即pip install natsort

【讨论】:

    【解决方案4】:

    实际上你不需要任何regex 模式。你可以这样轻松解析。

    >>> 'image101.jpg'[5:-4]
    '101'
    

    解决方案:

    >>> sorted(my_list, key=lambda x: int(x[5:-4]))
    ['image1.jpg', 'image2.jpg', 'image101.jpg']
    

    【讨论】:

      猜你喜欢
      • 2019-07-13
      • 2015-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-02
      • 2016-11-07
      • 2015-08-13
      • 1970-01-01
      相关资源
      最近更新 更多