Tipe variabel string gampang² susah untuk dipahami, sebenarnya tidak hanya di Python, tapi juga di hampir semua bahasa pemrograman. Kadang ia baik, kadang pemarah … eh salah … maksudnya selain mempengaruhi akurasi model data science/machine learning, program yang berjalan dengan baik bisa tiba² crash karena penanganan string yang tidak tepat. Di level produksi minimal ini adalah disaster level Dragon (OPM-😁).
![]() |
[Python 3 Unicode] |
Tulisan ini diambil terinspirasi dari video presentasi Ned Batchelder
T1 = "Hi, ini adalah contoh pertama string di Python 3" T2 = "dan ini adalah contoh kedua"
Lalu string tersebut sebenarnya adalah class/object yang bisa di akses dan operasikan seperti tuple/list, misal:
print(T1[:30] + T2[0:3] + T2[-6:] + " jika digabungkan")
outputnya adalah:
"Hi, ini adalah contoh pertama dan kedua jika digabungkan"
atau
print("Panjang string T1={0} dan panjang string T2={1}".format(len(T1),len(T2)))
outputnya:
"Panjang string T1=48 dan panjang string T2=27"
Lalu karena string adalah class/object, maka ia punya beberapa method, misal:
T1.split() # output => ['Hi,', 'ini', 'adalah', 'contoh', 'pertama', 'string', 'di', 'Python', '3'] print(T1[:3].upper() + T2[-6:].lower()) # output => "HI kedua"
Berikut ini kurang-lebih daftar Methods-nya:
Masalah selesai kan? Ga susah kan? …. Sayangnya … ini masih level beginner. Masalah akan mulai muncul ketika Text berasal dari sumber lain, misal dari aplikasi, media sosial, web, imported files, dsb. Untuk membahas string ke level berikutnya kita harus mulai dari teori ala kuliah dulu waktu di TK Penerbangan jurusan Sastra Komputer. Kita akan pakai konsep Ned Batchelder dalam membahas ini : “5 Fakta + 3 tips profesional“.
Fakta #1 : Komputer Mengolah Text dalam Bytes
![]() |
[Kira-The Matrix 😎] |
![]() |
[Encoding Byte to character using only 1 byte, source @nedbat bit.ly/unipain] |
Fakta #2: Dunia butuh lebih dari 1 byte characters
print([ord(t) for t in T1]) # output => [72, 105, 44, 32, ... , 110, 32, 51]
di Python kita juga bisa melakukan hal ini:
print("\N{GREEK CAPITAL LETTER DELTA}") # output (system dependent) => 'Δ'
di Python 3 default string adalah str dan str ini adalah Unicode:
print(type(T1)) # output => str
Kalau kita mau menyimpan teks dalam bytes, maka di Python 3 perintahnya seperti ini:
T3 = b"Hi, ini adalah contoh pertama string di Python 3"
Perhatikan ada “b” kecil sebelum tanda ” pertama. Kalau kita lakukan perintah
print(type(T3))
Maka outputnya adalah “bytes”.
Python string dalam bytes tetap bisa dioperasikan sebagaimana unicode string, misal fungsi split, strip, lower, dsb. Apakah dengan ini maka sebaiknya kita cukup memahami atau memakai satu tipe saja (bytes/unicode)? …. Sayangnya tidak. Mengapa? Nanti kita bahas di Fakta #3. Sebelum kesana saya mau mengingatkan hal berikut:
print(b"hi"=="hi") # output => False
Artinya hati-hati dalam menyimpan string di Python, yakinkan semua seragam dalam bentuk tertentu yang seragam Unicode atau bytes (Unicode is recommended-Nanti ada di Pro tips #1).
Fakta #3: Kita Harus Memahami Keduanya: Bytes dan Unicode
Ok berikut contoh sederhananya. Misal client mengirim suatu text (“你好” : “Hello There”):
T4 = b'\xe4\xbd\xa0\xe5\xa5\xbd' # pesan sebenarnya = "你好"
Lalu file tersebut di simpan dalam sebuah file atau dikirim lewat internet ke aplikasi kita. Ingat pesan disimpan dan dikirim oleh komputer dalam bentuk bytes (Fakta #1). Sehingga ketika pesan itu sampai ke server/komputer, kita perlu men-decodenya. Apabila kita berfikir pesannya dalam bentuk ASCII dan melakukan hal ini:
T4.decode(encoding='ascii') # output => Error!!!!.... Disaster happen!...
Mengapa? Karena karakter di T4 tidak bisa di petakan di tabel pemetaan ASCII. Atau kode pemetaannya diluar domainnya si ASCII. Tapi kalau kita lakukan ini:
print(T4.decode(encoding='utf-8'))
Maka outputnya benar = “你好”. Sehingga sampailah kita pada Fakta #4.
Fakta #4: Encoding tidak bisa di infer (ketahui secara otomatis)
Loh bukannya kita bisa Trial and error aja dalam melakukan encoding? Misal:
List_Encodings = [e1,e2,...,eN] # Misal e1, e2, ... eN adalah berbagai macam encodings.
lalu lakukan:
for encoding in List_Encodings : try: T4.decode(encoding=encoding) break #Stop nyoba kalau ndak error except: pass # Nyobain encoding berikutnya kalau terjadi error
Iya kan? iya kan? …. bisa kan? …. #NgarepSambilPasangMataCute #AlaKucing #TapiNdakImut
[Ilustrasi (contoh) mengapa coba² encoding is a bad idea] |
with open('FileTeks.txt', encoding='utf-8', mode='rt') as file: for baris in file: print(baris)
Atau jika ingin jika ingin membacanya dalam encoding Arabic (cp720) dalam bentuk bytes, berarti perintahnya jadi seperti ini:
with open('FileTeks.txt', encoding='cp720', mode='rb') as file: for baris in file: print(baris)
Daftar tipe “mode”-nya bisa diakses disini dan daftar encoder Python (>100) bisa di dapatkan disini. Bisa juga menggunakan “codecs” dan (misal) kita ingin write ke file maka jadi ndak perlu hawatir lagi dengan encoding-decoding:
import codecs f = codecs.open('file.txt','w','utf-8') f.write(Unicode_string) # Stored on disk as UTF-8
Apakah masalah kita sudah selesai sampai disini? … Maaf gan… belum … 😅 … Sampailah kita pada Fakta terakhir.
Fakta #5: People Lies, Data is Dirty
Sayangnya meta information yang diberikan di dalam file yang kita terima/buka tidak selamanya benar/konsisten. Begitu juga jika Agan memberikan software/app/sistem ke client dan memberikan requirement ke mereka bahwa system hanya bisa menerima (misal) utf-8 input dan output, tapi mungkin saja bisa terjadi dimana inputnya diluar batasan tersebut.
Hal ini juga terjadi ketika mengolah data media sosial. Terkadang walau di meta (profile) user datanya terindikasi “en” atau “id”, bukan berarti post-nya selalu mengikuti bahasa tersebut. Belum ditambah para Alayers yang sudah kita bahas sebelumnya. Tapiii… ga usah hawatir kok, ada beberapa trik yang bisa dilakukan/consider untuk menangani hal ini. Tapi dibahwas di tulisan lain saja ya. Yang ini sudah kepanjangan.
Inilah saatnya membahas 3 Pro Tips dari Pak Ned Batchelder.
Pro Tips#1: Sandwhich Method
Intinya “byte-Unicode-byte”, artinya data diterima/buka dalam bentuk bytes, tapi kemudian segera rubah dalam bentuk unicode ketika masuk sistem (misal NLP analytics). Kemudian di akhir sekali dari prosesnya kembali ke bytes (ilustrasinya Pak Ned). Tapi kalau bagi orang Data Science atau orang Social Media Analytics, “menurut saya” ndak begitu perlu juga melakukan sandwhich ini. Karena output biasanya berupa hasil analisa baik berupa model, visualisasi, atau interpretasinya. Tentu saja lain cerita lagi bagi rekan-rekan di (big) data engineer. Gagal menangani string ini akan berakibat kehilangan data atau minimal rusak/hilangnya data dalam jumlah yang bisa jadi sangat signifikan.
Pro tips #2: Mengetahui Tipe Data saat ini (bytes/unicode)
Ini sebenarnya kalau kata orang Sunda:” it goes without saying” atau bahasa Jerman-nya “ya iyalaaahhh” … Seandainya tips #1 dijalankan dengan baik, tips #2 ini juga jadi tidak terlalu penting. Tapi jika ragu ga ada salahnya gunakan perintah “type” di Python untuk memeriksa tipe string yang sekarang sedang digunakan.
Pro tips #3: Testing
Saya juga punya beberapa tips personal sederhana:
Kalau Agan punya tips dan ingin di share (sebagai amalan Agan 🙂 ), silahkan comment di bawah.
[1]. Mengetahui suatu string ASCII atau bukan:
Agan bisa lakukan ini untuk memeriksa/filtering non Ascii Texts:
isascii = lambda s: len(s) == len(s.encode())
Lalu menggunakan fungsi tersebut dengan cara seperti ini:
if isascii(word):
print(word)
[2]. Encoding with Exceptions
Zen Python bilang: “Errors should never pass silently. Unless explicitly silenced.”
Untuk menghindari error encoding, kita bisa menambahkan parameter exception “ignore”, misal:
T4.decode(encoding=”utf-8″, errors=”ignore”)
Pilihan error handling lainnya bisa ‘strict’ (default), ‘replace’, ‘xmlcharrefreplace’, ‘backslashreplace’ atau sembarang codecs register error (baca disni). Walau dengan ignore kita bisa menghindari Disaster level dragon, tapi … sebaiknya “menurut saya” kita tetap berhati-hati dengan encoding error ini. Misal kasusnya jika sekelompok data dari client memang menggunakan string dengan encoding diluar kebiasaan. Atau ketika kita mau mendeteksi percakapan khusus di suatu sistem (misal para koruptor atau teroris). Maka ada baiknya melakukan Try and catch, misal.
try: T4.decode(encoding="utf-8", errors="strict") except: TheExceptionsList.append(T4)
Ketika TheexceptionList membesar, kita mulai curiga ada udang dibalik bakwan. Lalu lakukan sesuatu akannya. Di Data Science/Sosial Media Analytics/NLP exceptions ini sebenarnya jika tidak signifikan jumlahnya sebenarnya tidak terlalu bermasalah (kita bahas nanti di post lain).
Ascii bisa direpresentasikan dengan utf-8, tapi tidak sebaliknya. (Ini dibahas di videonya Pak Ned). Intinya our safest bet adalah utf-8.
[4]. Read dalam bytes terkadang lebih cepat [Link]
[5]. Code Snippet ini:
You must log in to post a comment.