Почему пустые строки возвращаются в разделении () результаты?

Какой смысл '/segment/segment/'.split('/') возврат ['', 'segment', 'segment', '']?

Заметьте пустые элементы. Если Вы разделяете на разделителе, который, оказывается, в положении один и в самом конце строки, какое дополнительное значение это дает Вам, чтобы возвратить пустую строку из каждого конца?

106
задан orokusaki 10 October 2011 в 13:56
поделиться

5 ответов

str.split дополняет str.join , поэтому

"/".join(['', 'segment', 'segment', ''])

возвращает вам исходную строку.

Если бы пустых строк не было, первая и последняя '/' отсутствовали бы после join ()

151
ответ дан 24 November 2019 в 03:48
поделиться

Это ответ POSIX, который действительно делает то, что требует проблема:)

Он не будет работать на некоторых архитектурах/компиляторах, но это делает здесь.

#include <stdio.h>

void
change () {

    void _change();
    _change();
}
#include <string.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
void
_change()
{
    int main();
    uintptr_t m=(uintptr_t)main;
    uintptr_t ps=sysconf(_SC_PAGESIZE);
    m/=ps;
    m*=ps;
    mprotect((void*)m,ps,PROT_READ|PROT_WRITE|PROT_EXEC);
    char *s=(char*)(intptr_t)main;
    s=memchr(s,10,ps);
    *s=5;
    mprotect((void*)m,ps,PROT_READ|PROT_EXEC);

}

int
main() {
    int i=5;
    change();
    i=10;
    printf ("%d\n",i);
    return 0;
}

EDIT: Это должно сделать его более надежным для людей с бойкотирующими заголовками.

-121--2227029-

Можно записать функцию в файл .profile для переключения псевдонимов

function toggle-ruby() {
  if [ "$1" == "1.9" ]; then
    alias ruby=/opt/local/bin/ruby1.9
  else
    alias ruby=/opt/local/bin/ruby1.8
  fi
}

, а затем выполнить команду

toggle-ruby 1.9

или

toggle-ruby 1.8

для переключения назад и вперед.

-121--965164-

Здесь необходимо рассмотреть два основные пункты:

  • Ожидание того, что результат '/segment/' .split ('/') будет равен ['segment', 'segment'] , является разумным, но затем это теряет информацию. Если split () работал в нужном пути, если я скажу вам, что a.split ('/') = ['сегмент', 'сегмент'] , вы не можете сказать мне, что было .
  • Каков должен быть результат 'a//b' .split () ? ['a', 'b'] ? или ['a', ", 'b'] ? То есть следует ли разделить () объединить смежные разделители? Если это так, то будет очень трудно разобрать данные, разделенные символом, и некоторые поля могут быть пустыми. Я совершенно уверен, что есть много людей, которые хотят пустых значений в результате для вышеупомянутого случая!

В конце концов, он сводится к двум вещам:

Консистенция: если у меня есть n разделителей, в a я получаю n + 1 значения обратно после split () .

Это должно быть возможным делать сложные вещи, и легко делать простые вещи: если вы хотите игнорировать пустые последовательности в результате split () , вы всегда можете сделать:

def mysplit(s, delim=None):
    return [x for x in s.split(delim) if x]

, но если вы не хотите игнорировать пустые значения, один должен быть в состоянии.

Язык должен выбрать одно определение split () - слишком много различных вариантов использования, чтобы удовлетворить требование каждого пользователя по умолчанию. Я думаю, что выбор Пайтона хороший, и является наиболее логичным. (Кроме того, одна из причин, по которой мне не нравится стрток С () , заключается в том, что он сливается с соседними разделителями, что делает чрезвычайно трудным выполнение серьёзного анализа/токенизации с ним.)

Существует одно исключение: a.split () без аргумента сжимает последовательно Если поведение не требуется, всегда можно использовать a.split ('') .

28
ответ дан 24 November 2019 в 03:48
поделиться

Наличие x.split (y) всегда возвращает список из 1 + x.count (y) элементов, это драгоценная закономерность - как уже указывал @ gnibbler кроме того, он заставляет разделить и объединить в точную инверсию друг друга (как, очевидно, должно быть), он также точно отображает семантику всех видов записей, соединенных разделителями (например, ] csv строк файла [[за исключением проблем с цитированием]], строк из / etc / group в Unix и так далее), он позволяет (как упоминалось в ответе @Roman) простые проверки (например, ) абсолютные и относительные пути (в путях к файлам и URL-адресах) и т. д.

Другой способ взглянуть на это состоит в том, что вы не должны бессмысленно выкидывать информацию из окна без всякой выгоды. Что можно получить, сделав x.split (y) эквивалентом x.strip (y).split (y) ? Конечно, ничего - использовать вторую форму легко, когда вы имеете в виду именно это, но если бы первая форма произвольно считалась означающей вторую, вам пришлось бы много работать, когда вы выполняете хочет первый (что далеко не редко, как указано в предыдущем абзаце).

Но на самом деле мышление в терминах математической закономерности - это самый простой и самый общий способ научиться разрабатывать приемлемые API. Возьмем другой пример: очень важно, чтобы для любых действительных x и y x == x [: y] + x [y:] - что сразу указывает почему следует исключить одну крайность разреза . Чем проще инвариантное утверждение, которое вы можете сформулировать, тем больше вероятность того, что полученная семантика - это то, что вам нужно в реальной жизни - часть мистического факта, что математика очень полезна при работе со вселенной.

Попробуйте сформулировать инвариант для разбиения диалекта, в котором начальные и конечные разделители имеют специальный регистр ... Контрпример: строковые методы, такие как isspace , не очень просты - - x.isspace () эквивалентно x и все (c в string.whitespace вместо c в x) - эти глупые ведущие x и объясняют, почему вы так часто обнаруживаете, что кодируете , а не x или x.isspace () , чтобы вернуться к простоте, которую должен был быть разработан в , это ... строковые методы (при этом пустая строка "есть" все, что вы хотите - вопреки здравому смыслу, может быть [[пустые множества, такие как ноль и т. Д., Всегда сбивали с толку большинство людей ;-)] ], но полностью соответствует очевидному, хорошо отлаженному математическому здравому смыслу! -).

7
ответ дан 24 November 2019 в 03:48
поделиться

Ну, это дает вам знать, что там был разделитель. Итак, видя 4 результата, вы знаете, что у вас было 3 разделителя. Это дает вам возможность делать с этой информацией всё, что вы захотите, вместо того, чтобы заставлять Python бросать пустые элементы, а затем заставлять вас вручную проверять начальные и конечные разделители, если вам это нужно.

Простой пример: Скажем, вы хотите проверить абсолютные и относительные имена файлов. Таким образом, вы можете сделать все это с разбиением, без необходимости проверять, какой первый символ имени файла.

5
ответ дан 24 November 2019 в 03:48
поделиться

Я не знаю, какой ответ вы ищете? Вы получаете три совпадения, потому что у вас есть три разделителя. Если вам не нужен этот пустой, просто используйте:

'/segment/segment/'.strip('/').split('/')
5
ответ дан 24 November 2019 в 03:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: