Jaki jest sens '/segment/segment/'.split('/')
powrotu ['', 'segment', 'segment', '']
?
Zwróć uwagę na puste elementy. Jeśli dzielisz się na ograniczniku, który znajduje się na pierwszej pozycji i na samym końcu ciągu, jaką dodatkową wartość daje ci to, że pusty ciąg jest zwracany z każdego końca?
strip()
do usunięcia wiodących i końcowych znaków podziału z ciągu przed podziałem:'/segment/segment/'.strip('/').split('/')
Odpowiedzi:
str.split
uzupełnieniastr.join
, takprzywraca oryginalny ciąg.
Gdyby nie było pustych ciągów, nie
'/'
byłoby pierwszego i ostatniego pojoin()
źródło
Bardziej ogólnie, aby usunąć puste ciągi zwracane w
split()
wynikach, możesz przyjrzeć sięfilter
funkcji.Przykład:
zwroty
źródło
list(...)
.Należy wziąć pod uwagę dwie główne kwestie:
'/segment/segment/'.split('/')
będzie równy,['segment', 'segment']
jest rozsądne, ale wtedy powoduje to utratę informacji. Jeślisplit()
działało tak, jak chciałeś, jeśli ci powiema.split('/') == ['segment', 'segment']
, nie możesz mi powiedzieć, coa
było.'a//b'.split()
bycia?['a', 'b']
? lub['a', '', 'b']
? Czyli należysplit()
łączyć sąsiednie ograniczniki? Gdyby tak było, bardzo trudno będzie przeanalizować dane oddzielone znakiem, a niektóre pola mogą być puste. Jestem całkiem pewien, że wielu ludzi, którzy zrobienia chcą pustych wartości w wyniku dla powyższego przypadku!Ostatecznie sprowadza się to do dwóch rzeczy:
Spójność: jeśli mam
n
ograniczniki, wa
, otrzymujęn+1
wartości z powrotem posplit()
.Powinno być możliwe wykonywanie skomplikowanych rzeczy i łatwe do robienia prostych rzeczy: jeśli chcesz zignorować puste ciągi znaków jako wynik
split()
, zawsze możesz zrobić:ale jeśli ktoś nie chce ignorować pustych wartości, powinien być w stanie.
Język musi wybrać jedną definicję
split()
- jest zbyt wiele różnych przypadków użycia, aby domyślnie spełnić wymagania wszystkich. Myślę, że wybór Pythona jest dobry i najbardziej logiczny. (Na marginesie, jednym z powodów, dla których nie lubię C jeststrtok()
to, że łączy sąsiednie ograniczniki, co sprawia, że niezwykle trudno jest przeprowadzić z nim poważną analizę / tokenizację).Jest jeden wyjątek:
a.split()
bez argumentu ściska kolejne białe spacje, ale można argumentować, że w takim przypadku jest to właściwe postępowanie. Jeśli nie chcesz takiego zachowania, zawsze możesz to zrobića.split(' ')
.źródło
python3 -m timeit "import re ; re.sub(' +', ' foo bar baz ', '').split(' ')"
-> 875 nsec na pętlę;python3 -m timeit "[token for token in ' foo bar baz '.split(' ') if token]"
-> 616 nsec na pętlęMając
x.split(y)
zawsze zwróci listę1 + x.count(y)
elementów jest cennym regularność - jak @ gnibbler już zauważył to sprawiasplit
ijoin
dokładne odwrotności siebie (jak oczywiście powinny być), ale również precyzyjnie odwzorowuje semantykę wszystkich rodzajów płyt separatorów mikrowczepy ( takie jakcsv
wiersze pliku [[bez cudzysłowów]], wiersze z/etc/group
systemu Unix i tak dalej), umożliwia (jak wspomniano w odpowiedzi @ Romana) łatwe sprawdzenie (np.) ścieżek bezwzględnych i względnych (w ścieżkach plików i adresach URL), i tak dalej.Innym sposobem spojrzenia na to jest to, że nie powinieneś bezmyślnie wyrzucać informacji przez okno bez żadnych korzyści. Co można by zyskać, gdybyśmy byli
x.split(y)
równoważnix.strip(y).split(y)
? Nic, oczywiście - jest łatwy w użyciu drugą formę, gdy to, co masz na myśli, ale jeśli pierwsza forma została arbitralnie uznane oznaczać drugi, to że mają wiele do zrobienia, jeśli nie chcą pierwsza ( co nie jest rzadkie, jak wskazano w poprzednim akapicie).Ale tak naprawdę myślenie w kategoriach matematycznej regularności jest najprostszym i najbardziej ogólnym sposobem, w jaki możesz nauczyć się projektować zadowalające API. Aby wziąć inny przykład, bardzo ważne jest, aby dla każdego ważnego
x
iy
x == x[:y] + x[y:]
- co natychmiast wskazuje, dlaczego należy wykluczyć jedną skrajność krojenia . Im prostsze niezmienne twierdzenie możesz sformułować, tym bardziej prawdopodobne jest, że wynikająca z niego semantyka jest tym, czego potrzebujesz w prawdziwym życiu - część mistycznego faktu, że matematyka jest bardzo przydatna w radzeniu sobie ze wszechświatem.Spróbuj sformułować niezmiennik dla
split
dialektu, w którym początkowe i końcowe ograniczniki są umieszczone w specjalnej wielkości liter ... kontrprzykład: metody łańcuchowe, takie jakisspace
nie są maksymalnie proste -x.isspace()
jest równoważnex and all(c in string.whitespace for c in x)
- to głupie prowadzeniex and
jest powodem, dla którego tak często znajdujesz się w kodowaniunot x or x.isspace()
, aby powrócić do prostoty, która powinna zostać zaprojektowana wis...
metodach łańcuchowych (gdzie pusty łańcuch "jest" wszystkim, czego chcesz - w przeciwieństwie do wyczucia konia na ulicy, może [[puste zestawy, takie jak zero & c, zawsze myliły większość ludzi ;-)]], ale w pełni zgodne z oczywistym, dobrze wyrafinowanym zdrowym rozsądkiem matematycznym ! -).źródło
Nie wiem, jakiej odpowiedzi szukasz? Otrzymujesz trzy dopasowania, ponieważ masz trzy ograniczniki. Jeśli nie chcesz tego pustego, po prostu użyj:
źródło
Cóż, pozwala ci wiedzieć, że był tam separator. Tak więc wyświetlenie 4 wyników pozwala zorientować się, że masz 3 ograniczniki. Dzięki temu możesz robić, co chcesz z tymi informacjami, zamiast zmuszać Pythona do usuwania pustych elementów, a następnie zmuszać Cię do ręcznego sprawdzania początkowych lub końcowych ograniczników, jeśli chcesz to wiedzieć.
Prosty przykład: załóżmy, że chcesz sprawdzić bezwzględne i względne nazwy plików. W ten sposób możesz to wszystko zrobić z podziałem, bez konieczności sprawdzania pierwszego znaku nazwy pliku.
źródło
Rozważ ten minimalny przykład:
split
musi podać to, co znajduje się przed i za separatorem'/'
, ale nie ma innych znaków. Więc to ma dać wam pusty ciąg znaków, który technicznie poprzedza i następuje'/'
, ponieważ'' + '/' + '' == '/'
.źródło