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

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

如果你想首先按照右侧数字升序排序,然后按照左侧字符串排序,你应该交换sint(n),变成return int(n), s。否则 - 答案很好! - dawg

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
你可以使用正则表达式和关键的 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的排序是稳定的,如果您想按照下划线左侧的字符串和右侧的数字进行排序,请对列表进行两次原地排序:
>>> 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))

通常而言,进行两次排序比进行一次复杂的排序更快。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接