拆分函数 - 避免最后一个空格

16
我对如何使用split函数有疑问。
str = 'James;Joseph;Arun;'
str.split(';')

我得到了结果['James', 'Joseph', 'Arun', '']

我需要输出为['James', 'Joseph', 'Arun']

最好的方法是什么?


4
请不要使用 str 作为变量名。它会隐藏内置的 str - Mark Byers
@ Mark Byers 谢谢您的评论,我的实际变量名称不同。 - Jisson
2个回答

27
为了删除所有的空字符串,您可以使用列表推导式:
>>> [x for x in my_str.split(';') if x]

或者使用过滤器/布尔技巧:
>>> filter(bool, my_str.split(';'))

请注意,这也会删除列表开头或中间的空字符串,而不仅仅是末尾。 如果您只想删除末尾的空字符串,可以在拆分之前使用rstrip
>>> my_str.rstrip(';').split(';')

3
直到现在我才听说过 filer(bool,x),之前只知道 filter(None,x)。你认为哪一个更好? - jamylak
1
@jamylak:两种方法都可以。我更喜欢使用filter(bool, x),因为它让人更容易理解它的工作原理。使用None作为过滤函数似乎有点神奇(除非你已经阅读了文档才知道它的工作原理)。但是其他人可能更喜欢filter(None, x),所以我想这并没有太大的区别。 - Mark Byers

18

首先从字符串的右侧删除 ;

s.rstrip(';').split(';')

你还可以使用filter()函数(它将过滤掉在字符串末尾未找到的空元素)。但是,在我看来,上述方法真正最清晰简洁,当您想要避免由于字符串末尾出现";"字符而导致的空元素时,非常适用。

编辑:实际上比上述方法(其中上述方法仍然比使用filter()更准确)更准确的方法如下:

(s[:-1] if s.endswith(';') else s).split(';')

这将仅删除最后一个元素,只有在它变为空时才会删除。

测试这三个解决方案,您会发现它们会给出不同的结果:

>>> def test_solution(solution):
    cases = [
        'James;Joseph;Arun;',
        'James;;Arun',
        'James;Joseph;Arun',
        ';James;Joseph;Arun',
        'James;Joseph;;;',
        ';;;',
        ]
    for case in cases:
        print '%r => %r' % (case, solution(case))

>>> test_solution(lambda s: s.split(';'))  # original solution
'James;Joseph;Arun;' => ['James', 'Joseph', 'Arun', '']
'James;;Arun' => ['James', '', 'Arun']
'James;Joseph;Arun' => ['James', 'Joseph', 'Arun']
';James;Joseph;Arun' => ['', 'James', 'Joseph', 'Arun']
'James;Joseph;;;' => ['James', 'Joseph', '', '', '']
';;;' => ['', '', '', '']
>>> test_solution(lambda s: filter(bool, s.split(';')))
'James;Joseph;Arun;' => ['James', 'Joseph', 'Arun']
'James;;Arun' => ['James', 'Arun']
'James;Joseph;Arun' => ['James', 'Joseph', 'Arun']
';James;Joseph;Arun' => ['James', 'Joseph', 'Arun']
'James;Joseph;;;' => ['James', 'Joseph']
';;;' => []
>>> test_solution(lambda s: s.rstrip(';').split(';'))
'James;Joseph;Arun;' => ['James', 'Joseph', 'Arun']
'James;;Arun' => ['James', '', 'Arun']
'James;Joseph;Arun' => ['James', 'Joseph', 'Arun']
';James;Joseph;Arun' => ['', 'James', 'Joseph', 'Arun']
'James;Joseph;;;' => ['James', 'Joseph']
';;;' => ['']
>>> test_solution(lambda s: (s[:-1] if s.endswith(';') else s).split(';'))
'James;Joseph;Arun;' => ['James', 'Joseph', 'Arun']
'James;;Arun' => ['James', '', 'Arun']
'James;Joseph;Arun' => ['James', 'Joseph', 'Arun']
';James;Joseph;Arun' => ['', 'James', 'Joseph', 'Arun']
'James;Joseph;;;' => ['James', 'Joseph', '', '']
';;;' => ['', '', '']

2
在我看来,应该将其更改为 rstrip,因为他说的是最后一个空格。 - jamylak
1
@jamylak:没错,当你写评论的时候,我已经添加了那些信息。请查看更新后的答案。 - Tadeck

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