Python mengurutkan berdasarkan nilai byte secara default, yang berarti é muncul setelah z dan hal-hal lucu lainnya. Apa cara terbaik untuk mengurutkan menurut abjad dengan Python?
Apakah ada perpustakaan untuk ini? Saya tidak dapat menemukan apa pun. Pengurutan yang disukai harus memiliki dukungan bahasa sehingga memahami bahwa åäö harus diurutkan setelah z dalam bahasa Swedia, tetapi ü harus diurutkan berdasarkan u, dll. Dukungan Unicode dengan demikian cukup banyak merupakan persyaratan.
Jika tidak ada perpustakaan untuk itu, apa cara terbaik untuk melakukannya? Buat saja pemetaan dari huruf ke nilai integer dan petakan string ke daftar integer dengan itu?
locale.strcoll
jawabannya benar ketika Anda membutuhkan Unicode menyortir menggunakan lokal pengguna, dan jawaban ICU apa yang Anda inginkan ketika Anda membutuhkan lebih dari itu (pemeriksaan menggunakan lebih dari satu lokal). Sering kali, Anda menginginkannyalocale.strcoll
.locale.strcoll
bekerja dan terutama apa yang ICU lakukan lebih baik daripada fungsi Python. Pada dasarnya lebih banyak perhatian untuk pertanyaan itu.--locale=de__phonebook
saat Anda membutuhkannya. Modul Perl melewati rangkaian pengujian UCA, dan skrip yang saya sediakan membuatnya lebih mudah untuk dimainkan dengan seluruh UCA ditambah semua opsinya termasuk lokal, hanya dari baris perintah. Mungkin tidak menjawab dengan pertanyaan, tetapi masih harus sangat menarik. Jika Anda berada di Swiss, saya yakin Anda dapat menggunakan fleksibilitas. :)Jawaban:
Perpustakaan ICU IBM melakukan itu (dan banyak lagi). Ini memiliki binding Python: PyICU .
Pembaruan : Perbedaan inti dalam pengurutan antara ICU dan
locale.strcoll
ICU menggunakan Algoritma Penyusunan Unicode penuh saatstrcoll
menggunakan ISO 14651 .Perbedaan antara kedua algoritme tersebut dirangkum secara singkat di sini: http://unicode.org/faq/collation.html#13 . Ini adalah kasus khusus yang agak eksotis, yang dalam praktiknya jarang menjadi masalah.
sumber
locale.strxfrm
jawaban dari u0b34a0f6ae dan tampaknya berfungsi serta jauh lebih elegan dan tidak memerlukan perangkat lunak tambahan.sudo pip3 install PyICU
gagal dipasang dan begitu juga untuk Python2.Saya tidak melihat ini dalam jawaban. Aplikasi saya menyortir menurut lokal menggunakan pustaka standar python. Sangat mudah.
Pertanyaan untuk Lennart dan penjawab lainnya: Apakah tidak ada yang tahu 'lokal' atau tidak untuk tugas ini?
sumber
Coba Algoritma Penyusunan Python Unicode James Tauber . Ini mungkin tidak persis seperti yang Anda inginkan, tetapi tampaknya menarik untuk dilihat. Untuk sedikit lebih banyak informasi tentang masalah ini, lihat posting ini oleh Christopher Lenz.
sumber
Anda mungkin juga tertarik dengan pyuca :
http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/
Meskipun ini tentunya bukan cara yang paling tepat, ini adalah cara yang sangat sederhana untuk setidaknya membuatnya agak benar. Ini juga mengalahkan lokal di aplikasi web karena lokal bukanlah threadsafe dan menyetel pengaturan bahasa di seluruh proses. Ini juga lebih mudah untuk mengatur daripada PyICU yang mengandalkan perpustakaan C eksternal.
Saya mengunggah skrip ke github karena aslinya sedang tidak aktif pada saat penulisan ini dan saya harus menggunakan cache web untuk mendapatkannya:
https://github.com/href/Python-Unicode-Collation-Algorithm
Saya berhasil menggunakan skrip ini untuk mengurutkan teks Jerman / Prancis / Italia dengan baik dalam modul plone.
sumber
Ringkasan dan jawaban tambahan:
locale.strcoll
di bawah Python 2, danlocale.strxfrm
sebenarnya akan menyelesaikan masalah, dan melakukan pekerjaan dengan baik, dengan asumsi Anda telah menginstal lokal yang dimaksud. Saya mengujinya di bawah Windows juga, di mana nama lokal yang membingungkan berbeda, tetapi di sisi lain tampaknya memiliki semua lokal yang didukung diinstal secara default.ICU
tidak selalu melakukan ini dengan lebih baik dalam praktiknya, namun lebih dari itu . Terutama memiliki dukungan untuk pemisah yang dapat membagi teks dalam berbagai bahasa menjadi kata-kata. Ini sangat berguna untuk bahasa yang tidak memiliki pemisah kata. Anda harus memiliki kumpulan kata untuk digunakan sebagai dasar pemisahan, karena itu tidak termasuk.Ini juga memiliki nama panjang untuk lokal sehingga Anda bisa mendapatkan nama tampilan yang cantik untuk lokal, dukungan untuk kalender lain selain Gregorian (meskipun saya tidak yakin antarmuka Python mendukung itu) dan ton dan ton dukungan lokal lainnya yang kurang lebih tidak jelas .
Jadi semuanya: Jika Anda ingin mengurutkan menurut abjad dan bergantung pada lokal, Anda dapat menggunakan
locale
modul, kecuali Anda memiliki persyaratan khusus, atau juga memerlukan fungsionalitas yang lebih bergantung pada lokal, seperti kata-kata splitter.sumber
Saya melihat jawabannya telah melakukan pekerjaan yang sangat baik, hanya ingin menunjukkan satu ketidakefisienan pengkodean di Human Sort . Untuk menerapkan terjemahan char-by-char selektif ke string unicode s, itu menggunakan kode:
Python memiliki cara yang jauh lebih baik, lebih cepat dan lebih ringkas untuk melakukan tugas tambahan ini (pada string Unicode - metode analog untuk string byte memiliki spesifikasi yang berbeda dan agak kurang membantu! -):
Dikt yang Anda berikan ke
translate
metode memiliki ordinal Unicode (bukan string) sebagai kunci, itulah sebabnya kita membutuhkan langkah membangun kembali dari char-to-char aslispec_dict
. (Nilai dalam dict yang Anda berikan untuk diterjemahkan [sebagai lawan kunci, yang harus berupa ordinal] bisa berupa ordinal Unicode, string Unicode arbitrer, atau None untuk menghapus karakter terkait sebagai bagian dari terjemahan, sehingga mudah untuk menentukan "abaikan a karakter tertentu untuk keperluan penyortiran "," petakan ä ke ae untuk tujuan penyortiran ", dan sejenisnya).Di Python 3, Anda bisa mendapatkan langkah "membangun kembali" dengan lebih sederhana, misalnya:
Lihat dokumen untuk mengetahui cara lain menggunakan
maketrans
metode statis ini di Python 3.sumber
Untuk menerapkannya, Anda perlu membaca tentang "Algoritme pemeriksaan Unicode", lihat http://en.wikipedia.org/wiki/Unicode_collation_algorithm
http://www.unicode.org/unicode/reports/tr10/
contoh penerapannya ada di sini
http://jtauber.com/blog/2006/01/27/python_unicode_collation_algorithm/
sumber
Akhir-akhir ini saya menggunakan zope.ucol ( https://pypi.python.org/pypi/zope.ucol ) untuk tugas ini. Misalnya, mengurutkan bahasa jerman ß:
zope.ucol juga membungkus ICU, jadi akan menjadi alternatif untuk PyICU.
sumber
Solusi UCA Lengkap
Cara termudah, termudah, dan paling mudah untuk melakukannya adalah dengan membuat panggilan ke modul perpustakaan Perl, Unicode :: Collate :: Locale , yang merupakan subkelas dari modul Unicode :: Collate standar . Yang perlu Anda lakukan adalah meneruskan konstruktor dengan nilai lokal
"xv"
untuk Swedia.(Anda mungkin tidak perlu menghargai ini untuk teks bahasa Swedia, tetapi karena Perl menggunakan karakter abstrak, Anda dapat menggunakan titik kode Unicode apa pun sesuka Anda - tidak peduli platform atau build! Beberapa bahasa menawarkan kemudahan seperti itu. Saya menyebutkannya karena saya telah melawan kalah dalam pertempuran dengan Java karena masalah yang menjengkelkan akhir-akhir ini.)
Masalahnya adalah saya tidak tahu bagaimana mengakses modul Perl dari Python - selain itu, dari menggunakan shell callout atau pipa dua sisi. Untuk itu, oleh karena itu saya telah memberi Anda skrip kerja lengkap yang disebut ucsort yang dapat Anda panggil untuk melakukan apa yang Anda minta dengan mudah.
Skrip ini 100% sesuai dengan Algoritma Penyatuan Unicode lengkap , dengan semua opsi penyesuaian yang didukung !! Dan jika Anda memiliki modul opsional yang diinstal atau menjalankan Perl 5.13 atau yang lebih baik, Anda memiliki akses penuh ke lokal CLDR yang mudah digunakan. Lihat di bawah.
Demonstrasi
Bayangkan satu set input yang diurutkan dengan cara ini:
Urutan default berdasarkan hasil poin kode:
yang tidak benar oleh buku semua orang. Menggunakan skrip saya, yang menggunakan Unicode Collation Algorithm, Anda mendapatkan urutan ini:
Itu adalah jenis UCA default. Untuk mendapatkan lokal Swedia, panggil ucsort dengan cara ini:
Ini adalah demo masukan yang lebih baik. Pertama, set input:
Menurut kode poin, seperti ini:
Tetapi menggunakan UCA default membuatnya seperti ini:
Namun dalam bahasa Swedia, begini:
Jika Anda lebih suka mengurutkan huruf besar sebelum huruf kecil, lakukan ini:
Macam Disesuaikan
Anda dapat melakukan banyak hal lain dengan ucsort . Misalnya, berikut cara mengurutkan judul dalam bahasa Inggris:
Anda membutuhkan Perl 5.10.1 atau yang lebih baik untuk menjalankan skrip secara umum. Untuk dukungan lokal, Anda harus memasang modul CPAN opsional
Unicode::Collate::Locale
. Sebagai alternatif, Anda dapat menginstal versi pengembangan Perl, 5.13+, yang menyertakan modul itu secara standar.Konvensi Panggilan
Ini adalah prototipe cepat, jadi ucsort sebagian besar tidak didokumentasikan. Tetapi ini adalah SINOPSIS dari switch / opsi apa yang diterimanya pada baris perintah:
Ya, ok: itu benar-benar daftar argumen yang saya gunakan untuk panggilan
Getopt::Long
, tetapi Anda mengerti. :)Jika Anda dapat mengetahui cara memanggil modul pustaka Perl dari Python secara langsung tanpa memanggil skrip Perl, lakukanlah. Saya hanya tidak tahu bagaimana diri saya sendiri. Saya ingin mempelajari caranya.
Sementara itu, saya yakin skrip ini akan melakukan apa yang perlu Anda lakukan secara khusus - dan banyak lagi! Saya sekarang menggunakan ini untuk semua penyortiran teks. Itu akhirnya melakukan apa yang saya butuhkan untuk waktu yang sangat, sangat lama.
Satu-satunya downside adalah bahwa
--locale
argumen menyebabkan kinerja turun tabung, meskipun cukup cepat untuk penyortiran reguler, non-lokal tetapi masih 100% sesuai UCA . Karena memuat semua yang ada di memori, Anda mungkin tidak ingin menggunakan ini pada dokumen gigabyte. Saya menggunakannya berkali-kali sehari, dan itu pasti bagus karena akhirnya teks yang masuk akal.sumber
Hal ini jauh dari solusi lengkap untuk kasus penggunaan Anda, tapi Anda bisa melihat di unaccent.py script dari effbot.org. Apa yang pada dasarnya dilakukannya adalah menghilangkan semua aksen dari teks. Anda dapat menggunakan teks 'bersih' itu untuk mengurutkan menurut abjad. (Untuk penjelasan yang lebih baik lihat halaman ini .)
sumber
Jeff Atwood menulis posting yang bagus tentang Urutan Sortir Alami , di dalamnya ia menautkan ke skrip yang melakukan hampir semua yang Anda minta .
Ini bukan skrip sepele, dengan cara apa pun, tetapi itu berhasil.
sumber