对字符串中的“字段x”排序时的索引器错误,当不是所有字符串都拆分为“x”个字段数时

2024-09-30 22:15:44 发布

您现在位置:Python中文网/ 问答频道 /正文

此处简化的PyBites Code Challenges之一涉及按姓氏对姓名列表进行排序:

>>> names = ['Al Pacino', 'Matt Damon', 'Sandra Bullock', 'Keanu Reeves']
>>> sorted(names, key=lambda x: x.split()[1])
['Sandra Bullock', 'Matt Damon', 'Al Pacino', 'Keanu Reeves']

对于给定的示例,这种方法可以很好地工作,但是如果任何字符串拆分为少于两个部分,则会中断。例如,添加“麦当娜”:

^{pr2}$

也许可以用空字符串将拆分的字符串填充到所需的长度:

def last_name(name, last_name_field=2):
    name_split = name.split()
    while len(name_split) < 2:
        name_split.append('')
    return name_split[last_name_field - 1]

因此:

>>> names = ['Al Pacino', 'Madonna', 'Matt Damon', 'Sandra Bullock', 'Keanu Reeves']
>>> sorted(names, key=last_name)
['Madonna', 'Sandra Bullock', 'Matt Damon', 'Al Pacino', 'Keanu Reeves']

有更好的方法吗?在

澄清:迄今为止的答案提供了对拆分字符串中最后一个元素进行排序的替代方法。这些都很有用——谢谢!在

但是,由于我的问题没有充分说明——我的错——我真正想要的是一种对拆分字符串的给定元素(或字段)进行排序的方法,如果任何拆分字符串的字段数少于所需的数量,则不会引发异常并失败。在

本质上,我在寻找一种方法来获得与Unix sort命令相同的结果,如下面的示例,它对字段2进行排序:

$ sort +1 -2 Madonna.txt   # sorts by field 2
Madonna                    # without a field 2, sorts before the others
Leonardo Da Vinci          # sorts on Da (before Damon)
Matt Damon
Robert Downey Jr           # sorts on Downey, not Jr
Scarlett Johansson
Al Pacino

我的“填充”分割字符串的想法(见上文)是基于空字符串在非空字符串之前排序的观察结果,例如:

>>> sorted(['Al', 'Joe', 'Hachim', '', 'Greta'])
['', 'Al', 'Greta', 'Hachim', 'Joe']

那么,我的问题是,是否有更有效的方法来实现这个结果,是通过更有效地填充拆分字符串,还是采用完全不同的方法。在


Tags: 方法字符串namenames排序mattsplitlast
3条回答

如果您想要列表的最后一个元素,不要硬编码索引1,使用索引-1。在

>>> names = ['Al Pacino', 'Madonna', 'Matt Damon', 'Sandra Bullock', 'Keanu Reeves']
>>> sorted(names, key=lambda name: name.split()[-1])
['Sandra Bullock', 'Matt Damon', 'Madonna', 'Al Pacino', 'Keanu Reeves']

您可以使用str.rpartition来保证3元组响应,即使没有进行拆分,也会得到一个空字符串,例如:

>>> names = ['Al Pacino', 'Madonna', 'Matt Damon', 'Sandra Bullock', 'Keanu Reeves']
>>> sorted(names, key=lambda L: L.rpartition(' ')[2])
['Sandra Bullock', 'Matt Damon', 'Madonna', 'Al Pacino', 'Keanu Reeves']

它还针对一次拆分进行了优化,并且比使用str.splitmaxsplit=1一起使用更快(而且比在每个分隔符处拆分整个字符串要好得多)。在

可以使用切片:

def split_name(name, last_field=2):
    return name.split()[last_field-1:last_field]

split_name("Matt Damon") # => ["Damon"]
split_name("Madonna") # => []

相关问题 更多 >