Функция разделения - избегать последнего пустого пространства

У меня есть сомнение в том, как использовать функцию split.

str = 'James;Joseph;Arun;'
str.split(';')

Я получил результат ['James', 'Joseph', 'Arun', '']

Мне нужен вывод как ['James', 'Joseph', 'Arun']

Каков наилучший способ сделать это?

Ответы

Ответ 1

Чтобы удалить все пустые строки, вы можете использовать понимание списка:

>>> [x for x in my_str.split(';') if x]

Или трюк filter/bool:

>>> filter(bool, my_str.split(';'))

Обратите внимание, что это также удалит пустые строки в начале или в середине списка, а не только в конце.

Если вы просто хотите удалить пустую строку в конце, вы можете использовать rstrip перед расщеплением.

>>> my_str.rstrip(';').split(';')

Ответ 2

Сначала удалите ; с правого края строки:

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', '', '']
';;;' => ['', '', '']