2012-05-28 12 views
15

Mam wątpliwości, w jaki sposób korzystać z funkcji podziału.Funkcja podziału - unikanie ostatniej pustej przestrzeni

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

mam wynik ['James', 'Joseph', 'Arun', '']

muszę wyjście jako ['James', 'Joseph', 'Arun']

Jaki jest najlepszy sposób to zrobić?

+4

Proszę nie używać 'str' jako nazwy zmiennej. Ukrywa wbudowany 'str'. –

+0

@ Mark Byers dziękuję za komentarz, moje rzeczywiste var nazwa jest inna. – Jisson

Odpowiedz

23

Aby usunąć wszystkie puste struny można użyć wyrażeń listowych:

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

Albo Sztuką filtr/bool:

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

Należy pamiętać, że będzie to również usuwanie pustych strun na początku lub w środek listy, a nie tylko na końcu.

Jeśli chcesz po prostu wyjąć pusty łańcuch na końcu można używać rstrip przed podziału.

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

+1 Nie słyszałem o 'filer (bool, x)' do teraz, tylko 'filter (None, x)'. Który jest lepszy według Ciebie? – jamylak

+1

@jamylak: Obie są w porządku. Wolę 'filter (bool, x)', ponieważ czyni to bardziej oczywistym, dlaczego to działa. Używanie 'None' jako funkcji filtrowania wydaje się być magiczne (chyba że przeczytałeś dokumentację, aby dowiedzieć się, dlaczego to działa). Ale inni wolą 'filter (None, x)', więc domyślam się, że to nie robi wielkiej różnicy. –

16

Najpierw usuń ; od prawej krawędzi wyrażenie:

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

Można również wykorzystać filter() (który będzie odsączyć także pustych elementów, które nie zostały znalezione na końcu ciągu) . Ale powyższe jest, moim zdaniem, najczystszym podejściem, gdy chcesz uniknąć pustego elementu na końcu, wynikającego z ";" znaków występujących na końcu łańcucha.

EDIT: Właściwie bardziej dokładne niż wymienione powyżej (jeżeli powyższe jest jeszcze bardziej dokładne niż przy użyciu filter()) jest następujące podejście:

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

To usunie tylko ostatni element, i tylko wtedy, gdy zostanie utworzone jako puste.

Testowanie wszystkie trzy rozwiązania będzie można zobaczyć, że dają różne wyniki:

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

Proste i skuteczne –

+2

IMO zmienić na "rstrip", ponieważ wypowiedział ** ostatnie ** puste miejsce. – jamylak

+1

@jamylak: poprawne, dodawałem te informacje podczas pisania komentarza. Zobacz zaktualizowaną odpowiedź. – Tadeck

Powiązane problemy