Soru Neden boş dizeler split () sonuçlarında döndürülüyor?


Amacı nedir '/segment/segment/'.split('/') dönen ['', 'segment', 'segment', '']?

Boş öğeleri dikkat edin. Bir dizede ve bir dizenin sonunda bulunan bir sınırlayıcıya bölünürseniz, boş bir dizenin her iki uçtan döndürülmesini sağlamak için hangi ekstra değeri verirsiniz?


82
2018-02-04 05:14


Menşei


Aynı sorularım var ve uzun zamandır aradım. Şimdi boş sonuçların gerçekten önemli olduğunu anlıyorum. Sorunuz için teşekkürler. - Emerald Hieu
Bir çözüm kullanmaktır strip() ayrılmadan önce dizeden önde gelen ve sondaki bölünmüş karakterleri ayırmak için: '/segment/segment/'.strip('/').split('/') - pkamb


Cevaplar:


str.split tamamlar str.join, yani

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

orijinal dizgeyi geri alır.

Boş dizeler orada değilse, ilk ve son '/' sonra kayıp olurdu join()


125
2018-02-04 05:24



Basit, ama tamamen soruya cevap verir. - orokusaki
Kıvırcık tırnakların Python'da gerçekten geçerli olduğunu keşfetmek için şok oldum ... ama, ama ... nasıl? Dokümanlar bundan bahsetmiyorum. - Tim Pietzcker
@Tim, bende fikrim yok o tırnakların oraya nasıl girdiğini: - John La Rooy
Yani, Microsoft Word'ü Python IDE'niz olarak kullanmıyorsunuz, o zaman? :) - Tim Pietzcker
Basit cevapların en iyi olmadığını söyleyen aaa90210? Yanıtın nasıl basit olduğu konusunda bir yorum (önce 5 yıl önce) olmuştu, ama soruyu tam olarak yanıtladı. Bir cümlede "ama" kullanmak, kötü bir şey anlamına gelmez. Basit olmayan bir cevap daha eksiksiz bir cevap olabilir (örneğin, ilgili kararlar veya belirtilen işlevselliğe ilişkin bir PEP dahil). - orokusaki


Burada dikkate alınması gereken iki ana nokta vardır:

  • Sonucunu bekliyor '/segment/segment/'.split('/') eşit olmak ['segment', 'segment'] Makul, ama sonra bu bilgi kaybeder. Eğer split() sana anlatırsam, istediğin gibi çalıştı a.split('/') == ['segment', 'segment']bana ne diyemezsin a oldu.
  • Sonucu ne olmalı 'a//b'.split() olabilir mi? ['a', 'b']veya ['a', '', 'b']? I.e split() bitişik sınırlayıcıları birleştirmek? Gerekirse, bir karakterle sınırlandırılmış olan verileri ayrıştırmak çok zor olacaktır ve bazı alanlar boş olabilir. Oldukça eminim ki birçok insan var yap Yukarıdaki durum için sonuçtaki boş değerleri istiyorum!

Sonunda, iki şey aşağı kaynar:

Tutarlılık: eğer varsa n sınırlayıcılar, içinde a, Alırım n+1 sonra geri değerler split().

Karmaşık şeyler yapabilmeli ve basit şeyler yapmanın kolay olması gerekir: eğer boş dizeleri yok saymak istiyorsanız split(), her zaman yapabilirsiniz:

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

ama biri boş değerleri göz ardı etmek istemezse meli yapabilmek.

Dilin bir tanımını seçmek zorundadır split()- Herkesin gereksinimini varsayılan olarak karşılamak için çok farklı kullanım durumları vardır. Python'un seçiminin iyi bir şey olduğunu ve en mantıklı olduğunu düşünüyorum. (Bir yana, C'den hoşlanmadığım nedenlerden biri strtok() bitişik sınırlayıcıları birleştirdiği için, onunla ciddi ayrıştırma / belirleme yapmak çok zor hale gelir.)

Bir istisna var: a.split() bir argüman olmadan ardışık beyaz boşluk sıkar, ancak bu durumda bu doğru şey olduğunu iddia edebilir. Davranış istemiyorsanız, her zaman a.split(' ').


25
2018-02-04 05:44



+1, detay için teşekkürler. - orokusaki


Daha genel olarak, iade edilen boş dizeleri kaldırmak için split() sonuçlara bakmak isteyebilirsiniz filter işlevi.

Örnek:

filter(None, '/segment/segment/'.split('/'))

döner

['segment', 'segment']

23
2018-01-17 22:30



Bunun için teşekkürler, bu cevabın neden bu kadar uzak olduğunu bilmiyorum, her şey ilkel şeyler. - Wedge
Bir filtre nesnesini çıktı olarak almak yerine sonucu bir liste halinde toplamak isteniyorsa, tüm filtre yapısını list(...). - Tim Visée


sahip olan x.split(y) her zaman listesini döndür 1 + x.count(y) Öğeler değerli bir düzenliliktir - @ gnibbler'in zaten işaret ettiği gibi split ve join Birbirinin tam tersi (kesin olarak olması gerektiği gibi), aynı zamanda her türlü ayırıcı-birleşik kayıtların semantiklerini tam olarak eşler. csv dosya satırları [[alıntı sorunları net]], satırları /etc/group Unix'te, vb.), (@ Roman'ın cevabı belirtildiği gibi) (ör.) mutlak vs göreceli yollar (dosya yolları ve URL'ler) için vb.

Buna bakmanın başka bir yolu da, bilgisizce pencereden bilgi elde etmemelisiniz. Yaparken ne kazanılacak? x.split(y)eşittir x.strip(y).split(y)? Elbette ki, hiçbir şey ifade etmediğin zaman, ikinci formun kullanılması kolaydır, ama eğer ilk form keyfi olarak ikinci olanı saymışsa, senin için yapacak çok işin olurdu. yap Birincisini (önceki paragrafın belirttiği gibi nadir olmaktan uzak) isteyin.

Ama gerçekten, matematiksel düzenlilik açısından düşünmek, kendinizi pasif API'leri tasarlamak için kendinize öğretebileceğiniz en basit ve en genel yoldur. Farklı bir örnek almak gerekirse, herhangi bir geçerli için çok önemlidir. x ve y  x == x[:y] + x[y:] - hemen bir dilimlemenin neden bir aşırı olduğunu gösterir meli hariç tut Formüle edebileceğiniz değişmez iddianın daha basit olması, sonuçta ortaya çıkan semantiklerin gerçek yaşamda ihtiyaç duyduğunuz şey olması gerektiğidir - matematiklerin evrenle baş etmede çok yararlı olduğu mistik gerçeğin bir parçasıdır.

Bir değişkeni formüle etmeye çalışın split önde gelen ve sondaki sınırlayıcıların özel kasalı olduğu lehçe ... karşı örnek: dize yöntemleri gibi isspace en fazla basit değil - x.isspace() eşdeğerdir x and all(c in string.whitespace for c in x) - o aptal lider x and bu yüzden kendini sık sık kodladığın neden not x or x.isspace(), sadeliğe geri dönmek için meli içine dizayn edilmiştir is... dize yöntemleri (ki burada boş bir dizgedir) istediğiniz herhangi bir şeydir - sokaktaki insan at-anlamının tersine, belki [[sıfır ve c gibi boş kümeler çoğu insanı karıştırdı ;-)]], ama Tamamen rafine edilmiş olanlara tamamen uygun matematiksel sağduyu!-).


7
2018-02-04 05:50



Detaylı açıklama için +1. Teşekkürler Alex. - orokusaki


Ne tür bir cevap aradığına emin değilim. Üç eşleşme elde ettiğinden üç eşleşme elde edersiniz. Boş olanı istemiyorsan, sadece şunu kullan:

'/segment/segment/'.strip('/').split('/')

5
2018-02-04 05:21



-1 çünkü üç tane değil, dört tane de eşleşiyorsunuz ve bu da soruyu gerçekten cevaplamıyor. - Roman
Olumsuzlukla mücadele etmek için +1. Geriye üç sonuç alacağını söylemedi. Bana mantıklı gelen "üç sınırlayıcı" için "üç eşleşme" dedi. Bununla birlikte, hiçbir şeyden "dört eşleşme" almazsınız. Yine de sonuçta "dört element" aldınız. Ayrıca, doğrudan "neden" cevabını vermez, ama gerçekten istediğini elde etmenin basit bir yolunu sunar ... ... ki bence bu bir düşmanı hak etmiyor. Birini niteleyecekseniz (azalıyorsa, daha az değil) lütfen daha dikkatli olun! Şerefe! 8 ^) - wasatchwizard
@wasatchwizard Açıklama için teşekkürler. Düzeltme ve tavsiyeyi takdir ediyorum. Maalesef, şimdi oy kullanmam kilitlendi ve değiştirilemez. - Roman


Peki, orada bir sınırlayıcı olduğunu bilmeni sağlar. Yani, 4 sonucu görmek, 3 sınırlayıcınız olduğunu bilmenizi sağlar. Bu, Python'un boş öğeleri bırakmasını değil, daha sonra bunu bilmeniz gerekiyorsa sınırlayıcıları başlatmayı veya sonlandırmayı kontrol etmenizi sağlamaktan ziyade, bu bilgilerle istediğinizi yapma gücünü size verir.

Basit örnek: Mutlak ve ilgili dosya adlarını kontrol etmek istediğinizi varsayalım. Böylelikle, dosya adınızın ilk karakterinin ne olduğunu kontrol etmek zorunda kalmadan tümüyle bölme ile yapabilirsiniz.


5
2018-02-04 05:24



+1, teşekkürler dostum. - orokusaki