Apa gunanya '/segment/segment/'.split('/')
kembali ['', 'segment', 'segment', '']
?
Perhatikan elemen kosong. Jika Anda memisahkan pada pembatas yang kebetulan berada di posisi satu dan di ujung paling akhir string, nilai ekstra apa yang diberikannya agar string kosong dikembalikan dari setiap ujungnya?
strip()
untuk menghapus karakter yang dipisahkan di depan dan di belakangnya dari string sebelum memisahkan:'/segment/segment/'.strip('/').split('/')
Jawaban:
str.split
melengkapistr.join
, jadimendapatkan Anda kembali string aslinya.
Jika string kosong tidak ada, string pertama dan terakhir
'/'
akan hilang setelahjoin()
sumber
Secara lebih umum, untuk menghapus string kosong yang dikembalikan dalam
split()
hasil, Anda mungkin ingin melihatfilter
fungsinya.Contoh:
kembali
sumber
list(...)
.Ada dua hal utama yang perlu dipertimbangkan di sini:
'/segment/segment/'.split('/')
menjadi sama dengan['segment', 'segment']
adalah wajar, tetapi kemudian ini kehilangan informasi. Jikasplit()
bekerja seperti yang Anda inginkan, jika saya memberi tahu Anda itua.split('/') == ['segment', 'segment']
, Anda tidak dapat memberi tahu saya apa yanga
terjadi.'a//b'.split()
?['a', 'b']
?, atau['a', '', 'b']
? Yaitu, harussplit()
menggabungkan pembatas yang berdekatan? Jika harus, maka akan sangat sulit untuk mengurai data yang dibatasi oleh karakter, dan beberapa bidang bisa kosong. Saya cukup yakin ada banyak orang yang melakukan menginginkan nilai-nilai yang kosong dalam hasil untuk kasus di atas!Pada akhirnya, itu bermuara pada dua hal:
Konsistensi: jika saya memiliki
n
pembatas, dia
, saya mendapatkann+1
nilai kembali setelahsplit()
.Seharusnya mungkin untuk melakukan hal-hal kompleks, dan mudah untuk melakukan hal-hal sederhana: jika Anda ingin mengabaikan string kosong sebagai akibat dari
split()
, Anda selalu dapat melakukan:tetapi jika seseorang tidak ingin mengabaikan nilai kosong, Anda harus melakukannya bisa.
Bahasa harus memilih satu definisi
split()
— ada terlalu banyak kasus penggunaan yang berbeda untuk memenuhi persyaratan setiap orang sebagai default. Saya pikir pilihan Python itu bagus, dan paling logis. (Sebagai tambahan, salah satu alasan saya tidak suka C.strtok()
adalah karena ini menggabungkan pembatas yang berdekatan, membuatnya sangat sulit untuk melakukan parsing / tokenisasi yang serius dengannya.)Ada satu pengecualian:
a.split()
tanpa argumen menekan ruang kosong yang berurutan, tetapi orang dapat berargumen bahwa ini adalah hal yang benar untuk dilakukan dalam kasus itu. Jika Anda tidak menginginkan perilaku tersebut, Anda selalu bisaa.split(' ')
.sumber
python3 -m timeit "import re ; re.sub(' +', ' foo bar baz ', '').split(' ')"
-> 875 nsec per loop;python3 -m timeit "[token for token in ' foo bar baz '.split(' ') if token]"
-> 616 nsec per loopMemiliki
x.split(y)
selalu kembali daftar1 + x.count(y)
item adalah keteraturan berharga - sebagai @ gnibbler sudah menunjukkan itu membuatsplit
danjoin
invers yang tepat dari satu sama lain (karena mereka jelas harus), itu juga justru peta semantik semua jenis catatan pembatas-bergabung ( seperticsv
baris file [[masalah kutipan bersih]], baris dari/etc/group
dalam Unix, dan seterusnya), ini memungkinkan (seperti jawaban @ Roman disebutkan) pemeriksaan mudah untuk (misalnya) jalur absolut vs relatif (di jalur file dan URL), Dan seterusnya.Cara lain untuk melihatnya adalah bahwa Anda tidak boleh sembarangan membuang informasi dari jendela tanpa keuntungan. Apa yang akan diperoleh dengan membuat
x.split(y)
setarax.strip(y).split(y)
? Tidak ada, tentu saja - sangat mudah untuk menggunakan bentuk kedua ketika itu ini apa yang Anda maksud, tetapi jika bentuk pertama sewenang-wenang dianggap berarti yang kedua, Anda akan memiliki banyak pekerjaan yang harus dilakukan ketika Anda tidak ingin yang pertama ( yang jauh dari langka, seperti yang ditunjukkan paragraf sebelumnya).Tapi sungguh, berpikir dalam istilah keteraturan matematis adalah cara paling sederhana dan paling umum yang bisa Anda pelajari sendiri untuk merancang API yang lumayan. Untuk mengambil contoh yang berbeda, sangat penting bahwa untuk setiap yang valid
x
dany
x == x[:y] + x[y:]
- yang segera menunjukkan mengapa salah satu pemotongan harus dikecualikan. Semakin sederhana pernyataan invarian yang dapat Anda rumuskan, semakin mungkin semantik yang dihasilkan adalah yang Anda butuhkan dalam penggunaan kehidupan nyata - bagian dari fakta mistik bahwa matematika sangat berguna dalam menangani alam semesta.Cobalah merumuskan invarian untuk sebuah
split
dialek di mana pembatas utama dan pembatasnya dikurung khusus ... kontra-contoh: metode string sepertiisspace
tidak terlalu sederhana -x.isspace()
setara denganx and all(c in string.whitespace for c in x)
- bahwa petunjuk konyolx and
itulah mengapa Anda begitu sering menemukan diri Anda sedang membuat kodenot x or x.isspace()
, untuk kembali ke kesederhanaan yang seharusnya telah dirancang ke dalamis...
metode string (di mana string kosong "adalah" apa pun yang Anda inginkan - bertentangan dengan naluri manusia di jalan, mungkin [[set kosong, seperti nol & c, selalu membingungkan kebanyakan orang ;-)]], tetapi sepenuhnya sesuai dengan akal sehat matematis yang sangat halus ! -).sumber
Saya tidak yakin jawaban seperti apa yang Anda cari? Anda mendapatkan tiga kecocokan karena Anda memiliki tiga pembatas. Jika Anda tidak ingin yang kosong itu, cukup gunakan:
sumber
Nah, ini memberi tahu Anda bahwa ada pembatas di sana. Jadi, melihat 4 hasil memungkinkan Anda mengetahui bahwa Anda memiliki 3 pembatas. Ini memberi Anda kekuatan untuk melakukan apa pun yang Anda inginkan dengan informasi ini, daripada meminta Python menjatuhkan elemen kosong, dan kemudian membuat Anda memeriksa secara manual untuk memulai atau mengakhiri pembatas jika Anda perlu mengetahuinya.
Contoh sederhana: Misalnya Anda ingin memeriksa nama file absolut vs. relatif. Dengan cara ini Anda dapat melakukan semuanya dengan split, tanpa harus memeriksa karakter pertama dari nama file Anda.
sumber
Pertimbangkan contoh minimal ini:
split
harus memberi Anda apa sebelum dan sesudah pembatas'/'
, tetapi tidak ada karakter lain. Jadi itu harus memberi Anda string kosong, yang secara teknis mendahului dan mengikuti'/'
, karena'' + '/' + '' == '/'
.sumber