Fungsi Python 2 maketrans() tidak berfungsi dengan Unicode: panjang argumennya berbeda padahal sebenarnya

[Python 2] SUB = string.maketrans("0123456789","₀₁₂₃₄₅₆₇₈₉")

kode ini menghasilkan kesalahan:

ValueError: maketrans arguments must have same length

Saya tidak yakin mengapa ini terjadi karena panjang senarnya sama. Satu-satunya ide saya adalah bahwa panjang teks subskrip berbeda dari karakter ukuran standar tetapi saya tidak tahu bagaimana menyiasatinya.


person Aaron    schedule 07.05.2015    source sumber
comment
Berfungsi dengan baik di Python 3 (yang memang memiliki dukungan unicode yang jauh lebih bagus), apakah itu pilihan untuk Anda?   -  person Stefan Pochmann    schedule 07.05.2015
comment
saat ini saya menjalankan python 2.7 tetapi saya pasti akan melihat Python 3   -  person Aaron    schedule 07.05.2015
comment
Kode Python 3 itu berasal dari jawaban rapi @ZeroPiraeus untuk Mencetak subskrip dengan python   -  person smci    schedule 10.09.2018


Jawaban (1)


Tidak, argumennya tidak sama panjangnya:

>>> len("0123456789")
10
>>> len("₀₁₂₃₄₅₆₇₈₉")
30

Anda mencoba meneruskan data yang dikodekan; Saya menggunakan UTF-8 di sini, di mana setiap digit dikodekan menjadi masing-masing 3 byte.

Anda tidak dapat menggunakan str.translate() untuk memetakan byte ASCII ke urutan byte UTF-8. Dekode string Anda menjadi unicode dan gunakan metode unicode.translate() yang sedikit berbeda; dibutuhkan kamus sebagai gantinya:

nummap = {ord(c): ord(t) for c, t in zip(u"0123456789", u"₀₁₂₃₄₅₆₇₈₉")}

Ini akan membuat kamus yang memetakan titik kode Unicode (bilangan bulat), yang kemudian dapat Anda gunakan pada string Unicode:

>>> nummap = {ord(c): ord(t) for c, t in zip(u"0123456789", u"₀₁₂₃₄₅₆₇₈₉")}
>>> u'99 bottles of beer on the wall'.translate(nummap)
u'\u2089\u2089 bottles of beer on the wall'
>>> print u'99 bottles of beer on the wall'.translate(nummap)
₉₉ bottles of beer on the wall

Anda kemudian dapat mengkodekan output ke UTF-8 lagi jika diinginkan.

Dari dokumentasi metode:

Untuk objek Unicode, metode translate() tidak menerima argumen opsional deletechars. Sebaliknya, ia mengembalikan salinan s yang semua karakternya telah dipetakan melalui tabel terjemahan tertentu yang harus berupa pemetaan ordinal Unicode ke ordinal Unicode, string Unicode, atau None. Karakter yang belum dipetakan tidak akan tersentuh. Karakter yang dipetakan ke None dihapus.

person Martijn Pieters    schedule 07.05.2015
comment
apakah ada cara lain untuk mendapatkan karakter subskrip dengan python? atau bahkan cara untuk mengatasi perbedaan panjang ini - person Aaron; 07.05.2015
comment
Aaron: ini bukan batasan dari Python ... melainkan implikasi dari perbedaan antara ASCII dan Unicode. Tidak ada karakter subskrip di ASCII. Implikasi dari penggunaan karakter Unicode adalah bahwa Python tidak dapat memperlakukan karakter tersebut seolah-olah mereka adalah ASCII --- upaya apa pun untuk melakukannya mungkin berhasil pada beberapa kasus tetapi akan gagal pada kasus lainnya. - person Jim Dennis; 07.05.2015
comment
@Martijn Di mana Anda mendapatkan 30? Saya mendapatkan input 10 atau karakter Tidak Didukung, tergantung di mana saya mencobanya. - person Stefan Pochmann; 07.05.2015
comment
@StefanPochmann: menggunakan juru bahasa interaktif di terminal yang dikonfigurasi untuk penggunaan UTF-8. - person Martijn Pieters; 07.05.2015
comment
Hanya di Python 2. Panjangnya 30 di Python 2 dan 10 di Python 3. Kode OP berfungsi dengan baik di Python 3. - person smci; 10.09.2018
comment
@smci tepatnya; Anda hanya akan melihat kesalahan khusus ini di Python 2 karena ini adalah string byte. Itu sebabnya pertanyaannya ditandai dengan tag python-2.x. - person Martijn Pieters; 10.09.2018