如何根据子字符串对列表进行排序?

时间:2013-09-05 13:27:24

标签: python django

我将此列表排序:

>>> L = ['actor_1', 'actor_3', 'actor_130', 'actor_55', 'actor_5']
>>> L.sort()
>>> L
['actor_1', 'actor_130', 'actor_3', 'actor_5', 'actor_55']

是否有一种干净的方法可以使列表按下划线后的数字进行排序,使其具有以下内容?:

['actor_1', 'actor_3', 'actor_5', 'actor_55', 'actor_130']

3 个答案:

答案 0 :(得分:7)

您可以指定生成比较密钥的key函数:

>>> L = ['actor_1', 'actor_3', 'actor_130', 'actor_55', 'actor_5']
>>> def sort_key(s):
...     s, n = s.split('_')
...     return s, int(n)
...
>>> L.sort(key=sort_key)
>>> L
['actor_1', 'actor_3', 'actor_5', 'actor_55', 'actor_130']

答案 1 :(得分:2)

您可以将号码分成另一个列表并将它们排序在一起。

>>> L = ['actor_1', 'actor_3', 'actor_130', 'actor_55', 'actor_5']
>>> n = [int(x.split('_')[1]) for x in L]
>>> n
[1, 3, 130, 55, 5]
>>> L = [x for (y, x) in sorted(zip(n, L))]
>>> L
['actor_1', 'actor_3', 'actor_5', 'actor_55', 'actor_130']

答案 2 :(得分:1)

您可以使用正则表达式和密钥lambda:

>>> L.sort(key=lambda s: int(re.search(r'_(\d+)',s).group(1)))
>>> L
['actor_1', 'actor_3', 'actor_5', 'actor_55', 'actor_130']

由于Python的排序为stable,如果您希望列表首先按下划线左侧的字符串排序,然后按右侧的数字排序,只需按两次排序:

>>> L = ['actor_1', 'actor_3', 'actor_130', 'actor_55', 'voice_5', 'actor_5']
>>> L.sort()
>>> L.sort(key=lambda s: int(re.search(r'_(\d+)',s).group(1)))
>>> L
['actor_1', 'actor_3', 'actor_5', 'voice_5', 'actor_55', 'actor_130']

或者你可以通过在键函数中返回一个元组来对数字进行排序,然后在LH字符串上进行排序来做同样的事情:

>>> L.sort(key=lambda s: (int(re.search(r'_(\d+)',s).group(1)),s))
>>> L
['actor_1', 'actor_3', 'actor_5', 'voice_5', 'actor_55', 'actor_130']

或者:

>>> L.sort(key=lambda s: (int(s.split('_')[1]), s))

经常 faster做两种而不是一种复杂的排序。