4

我有这个列表排序:

>>> 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']
4

3 回答 3

8

您可以指定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']
于 2013-09-05T13:31:11.480 回答
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']
于 2013-09-05T13:31:26.340 回答
2

您可以使用正则表达式和键 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 的 sort 是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))

执行两种排序通常比执行一种复杂排序更快

于 2013-09-05T13:47:52.700 回答