Какой смысл '/segment/segment/'.split('/')
возвращаться ['', 'segment', 'segment', '']
?
Обратите внимание на пустые элементы. Если вы разделяете разделитель, который оказывается в первой позиции и в самом конце строки, какое дополнительное значение он дает, чтобы пустая строка возвращалась с каждого конца?
strip()
чтобы удалить'/segment/segment/'.strip('/').split('/')
Ответы:
str.split
дополняетstr.join
, поэтомувозвращает вам исходную строку.
Если бы пустых строк не было, то первая и последняя не
'/'
было бы послеjoin()
источник
В более общем смысле, чтобы удалить пустые строки, возвращаемые в
split()
результатах, вы можете посмотреть наfilter
функцию.Пример:
возвращается
источник
list(...)
.Здесь необходимо учитывать два основных момента:
'/segment/segment/'.split('/')
будет равен,['segment', 'segment']
разумно, но тогда теряется информация. Еслиsplit()
сработало так, как вы хотели, если я вам это скажуa.split('/') == ['segment', 'segment']
, вы не сможете мне сказать, чтоa
было.'a//b'.split()
?['a', 'b']
?, или['a', '', 'b']
? Т.е. надоsplit()
сливать соседние разделители? В противном случае будет очень сложно проанализировать данные, разделенные символом, а некоторые поля могут быть пустыми. Я довольно уверен , что есть много людей , которые делают хотят пустые значения в результате для вышеприведенного случая!В конце концов, все сводится к двум вещам:
Последовательность: если у меня есть
n
разделителиa
, я получаюn+1
значения обратно послеsplit()
.Должна быть возможность делать сложные вещи и легко делать простые: если вы хотите игнорировать пустые строки в результате
split()
, вы всегда можете сделать:но если кто-то не хочет игнорировать пустые значения, он должен иметь возможность.
Язык должен выбрать одно определение -
split()
существует слишком много различных вариантов использования, чтобы удовлетворить требования каждого по умолчанию. Я считаю, что выбор Python правильный и самый логичный. (Кстати, одна из причин, по которой мне не нравится C,strtok()
заключается в том, что он объединяет смежные разделители, что чрезвычайно затрудняет серьезный синтаксический анализ / токенизацию с ним.)Есть одно исключение:
a.split()
без аргумента сжимает последовательные пробелы, но можно возразить, что в этом случае это правильно. Если вы не хотите такого поведения, вы всегда можете это сделатьa.split(' ')
.источник
python3 -m timeit "import re ; re.sub(' +', ' foo bar baz ', '').split(' ')"
-> 875 нс на цикл;python3 -m timeit "[token for token in ' foo bar baz '.split(' ') if token]"
-> 616 нс на петлюИмея
x.split(y)
всегда возвращает список1 + x.count(y)
элементов является драгоценной закономерностью - а @ gnibbler уже указал, что делаетsplit
иjoin
точные обратный друг друг (как они , очевидно , должно быть), но и точно отображает семантику всех видов разделителей присоединенных записей ( такие какcsv
строки файлов [[за исключением проблем с цитированием]], строки из/etc/group
Unix и т. д.), он позволяет (как упоминалось в ответе @ Roman) легко проверять (например) абсолютные и относительные пути (в путях к файлам и URL-адресах), и так далее.Другой способ взглянуть на это состоит в том, что вы не должны бессмысленно выбрасывать информацию из окна без всякой выгоды. Что можно получить, сделав
x.split(y)
эквивалентx.strip(y).split(y)
? Ничего, конечно - вторую форму легко использовать, когда вы имеете в виду именно это, но если бы первая форма произвольно считалась означающей вторую, у вас было бы много работы, когда вам действительно нужна первая ( что далеко не редко, как указано в предыдущем абзаце).Но на самом деле мышление в терминах математической закономерности - это самый простой и самый общий способ научиться разрабатывать приемлемые API. Возьмем другой пример, очень важно, чтобы для любого действительного
x
иy
x == x[:y] + x[y:]
- это сразу указывает, почему следует исключить одну крайность среза . Чем проще инвариантное утверждение, которое вы можете сформулировать, тем больше вероятность того, что полученная семантика - это то, что вам нужно в реальной жизни - часть мистического факта, что математика очень полезна при работе со вселенной.Попробуйте сформулировать инвариант для
split
диалекта, в котором начальные и конечные разделители имеют специальный регистр ... контрпример: строковые методы, такие какisspace
не максимально простые -x.isspace()
эквивалентноx and all(c in string.whitespace for c in x)
- это глупое началоx and
, поэтому вы так часто обнаруживаете, что кодируетеnot x or x.isspace()
, чтобы вернуться к простоте, которая должна была бытьis...
реализована в строковых методах (при этом пустая строка "есть" все, что вы хотите - вопреки здравому смыслу прохожего, возможно [[пустые множества, например ноль & c, всегда сбивали с толку большинство людей ;-)]], но полностью соответствовали очевидному, хорошо отточенному математическому здравому смыслу! -).источник
Я не уверен, какой ответ вы ищете? Вы получаете три совпадения, потому что у вас есть три разделителя. Если вам не нужен этот пустой, просто используйте:
источник
Что ж, это позволяет узнать, что там был разделитель. Итак, видя 4 результата, вы узнаете, что у вас 3 разделителя. Это дает вам возможность делать с этой информацией все, что вы хотите, вместо того, чтобы Python отбрасывал пустые элементы, а затем заставлял вас вручную проверять наличие начальных или конечных разделителей, если вам нужно это знать.
Простой пример: предположим, вы хотите проверить абсолютные и относительные имена файлов. Таким образом, вы можете сделать все это с разделением, не проверяя также, какой первый символ в вашем имени файла.
источник
Рассмотрим этот минимальный пример:
split
должен указать, что до и после разделителя'/'
, но нет других символов. Таким образом, он должен предоставить вам пустую строку, которая технически предшествует и следует за'/'
, потому что'' + '/' + '' == '/'
.источник