Tipe Data #

Setiap nilai di Python memiliki tipe — dan tipe menentukan operasi apa yang bisa dilakukan terhadap nilai tersebut. Python bersifat strongly typed: tidak ada konversi implisit antara tipe yang tidak kompatibel. Kamu tidak bisa langsung menambahkan angka dengan string seperti di JavaScript. Tapi Python juga dynamically typed: tipe ditentukan saat runtime, bukan saat kompilasi. Memahami tipe data dengan baik — termasuk mana yang mutable dan mana yang immutable, bagaimana konversi bekerja, dan jebakan-jebakan yang tidak intuitif — adalah fondasi penting sebelum menulis kode Python yang lebih kompleks.

Peta Tipe Data Python #

Tipe Data Python
│
├── Skalar (nilai tunggal)
│   ├── int        → bilangan bulat: 42, -7, 0
│   ├── float      → bilangan desimal: 3.14, -0.5, 1e10
│   ├── complex    → bilangan kompleks: 3+4j
│   ├── bool       → True / False
│   └── NoneType   → None
│
└── Koleksi (kumpulan nilai)
    ├── Terurut & Mutable
    │   └── list   → [1, 2, 3]
    ├── Terurut & Immutable
    │   ├── tuple  → (1, 2, 3)
    │   └── str    → "hello"
    ├── Tidak Terurut & Mutable
    │   ├── dict   → {"key": "value"}
    │   └── set    → {1, 2, 3}
    └── Tidak Terurut & Immutable
        └── frozenset → frozenset({1, 2, 3})

int — Bilangan Bulat #

Python int tidak memiliki batas ukuran — bisa menampung bilangan bulat sebesar yang mampu ditampung memori. Ini berbeda dari bahasa seperti Java yang punya int (32-bit) dan long (64-bit).

# Literal integer dalam berbagai basis
desimal     = 255          # basis 10 (default)
biner       = 0b11111111   # basis 2  → 255
oktal       = 0o377        # basis 8  → 255
heksadesimal = 0xFF        # basis 16 → 255

print(desimal, biner, oktal, heksadesimal)
# → 255 255 255 255

# Python mendukung integer tak terbatas
faktorial_100 = 1
for i in range(1, 101):
    faktorial_100 *= i
print(faktorial_100)  # → angka 158 digit, tidak overflow!

# Operasi pembagian — perhatikan perbedaannya
print(10 / 3)    # → 3.3333... (selalu float, meski habis dibagi)
print(10 // 3)   # → 3         (pembagian bulat, hasilnya int)
print(10 % 3)    # → 1         (sisa bagi / modulo)
print(2 ** 10)   # → 1024      (pemangkatan)

# Pemisah ribuan untuk keterbacaan
populasi = 270_000_000
anggaran = 1_500_000_000
print(populasi)   # → 270000000

float — Bilangan Desimal #

float di Python menggunakan representasi IEEE 754 double precision (64-bit). Ini memberikan presisi sekitar 15–17 digit desimal, tapi juga membawa konsekuensi yang sering mengejutkan pemula.

# Literal float
pi      = 3.14159
avogadro = 6.022e23    # notasi ilmiah: 6.022 × 10²³
kecil   = 1.5e-10      # 1.5 × 10⁻¹⁰

print(avogadro)  # → 6.022e+23
print(kecil)     # → 1.5e-10

Jebakan Presisi Float #

# ANTI-PATTERN: membandingkan float secara langsung
print(0.1 + 0.2)          # → 0.30000000000000004 (bukan 0.3!)
print(0.1 + 0.2 == 0.3)   # → False  ← jebakan klasik!

# Mengapa? Karena 0.1 dan 0.2 tidak bisa direpresentasikan
# secara persis dalam biner (seperti 1/3 dalam desimal)

# BENAR: gunakan math.isclose() untuk perbandingan float
import math
print(math.isclose(0.1 + 0.2, 0.3))        # → True
print(math.isclose(0.1 + 0.2, 0.3, rel_tol=1e-9))  # → True

# Atau round() untuk membulatkan sebelum membandingkan
print(round(0.1 + 0.2, 10) == round(0.3, 10))  # → True
# ANTI-PATTERN: menggunakan float untuk kalkulasi uang/finansial
harga = 19.99
pajak = 0.11
total = harga * (1 + pajak)
print(total)  # → 22.18890000000000... (tidak presisi untuk uang!)

# BENAR: gunakan modul decimal untuk kalkulasi finansial
from decimal import Decimal, ROUND_HALF_UP

harga = Decimal("19.99")
pajak = Decimal("0.11")
total = harga * (1 + pajak)
print(total)  # → 22.1889

# Bulatkan ke 2 desimal
total_bulat = total.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP)
print(total_bulat)  # → 22.19
Jangan pernah gunakan float untuk kalkulasi yang melibatkan uang, keuangan, atau nilai yang memerlukan presisi desimal eksak. Gunakan modul decimal dari stdlib Python — dirancang khusus untuk kebutuhan ini.

str — String (Teks) #

String di Python adalah urutan karakter Unicode yang immutable — sekali dibuat, nilainya tidak bisa diubah. Setiap operasi string menghasilkan string baru.

# Cara membuat string
s1 = 'tanda kutip tunggal'
s2 = "tanda kutip ganda"
s3 = """string
multi-baris
dengan triple-quote"""
s4 = '''ini juga
bisa multi-baris'''

# String raw — backslash tidak diinterpretasi sebagai escape
path_windows = r"C:\Users\Budi\Documents"   # r = raw string
regex_pola   = r"\d+\.\d+"                  # berguna untuk regex
print(path_windows)  # → C:\Users\Budi\Documents

# String bytes — untuk data biner
data_biner = b"hello"
print(type(data_biner))  # → <class 'bytes'>

Operasi String Penting #

teks = "Selamat Datang di Python"

# Indexing dan slicing
print(teks[0])       # → S (indeks pertama)
print(teks[-1])      # → n (indeks terakhir)
print(teks[0:7])     # → Selamat
print(teks[8:])      # → Datang di Python
print(teks[:7])      # → Selamat
print(teks[::2])     # → SlmtDtn iPto (setiap 2 karakter)
print(teks[::-1])    # → nohtyP id gnataDtamlaleS (terbalik)

# Metode string yang sering dipakai
print(teks.upper())           # → SELAMAT DATANG DI PYTHON
print(teks.lower())           # → selamat datang di python
print(teks.split(" "))        # → ['Selamat', 'Datang', 'di', 'Python']
print(teks.replace("Python", "Dunia"))  # → Selamat Datang di Dunia
print("  spasi  ".strip())    # → spasi
print(teks.startswith("Sel")) # → True
print(teks.endswith("on"))    # → True
print("Python" in teks)       # → True
print(len(teks))              # → 24

Format String #

nama = "Budi"
skor = 92.5
peringkat = 3

# f-string (Python 3.6+) — cara yang direkomendasikan
print(f"Halo, {nama}!")                      # → Halo, Budi!
print(f"Skor: {skor:.1f}")                   # → Skor: 92.5
print(f"Skor: {skor:.0f}")                   # → Skor: 93 (dibulatkan)
print(f"Peringkat ke-{peringkat:02d}")        # → Peringkat ke-03
print(f"Nilai: {skor!r}")                    # → Nilai: 92.5
print(f"{'kiri':<10}|{'tengah':^10}|{'kanan':>10}")
# → kiri      |  tengah  |     kanan

# ANTI-PATTERN: concatenation dalam loop — sangat lambat untuk string panjang
kata_list = ["Python", "adalah", "bahasa", "yang", "hebat"]
hasil = ""
for kata in kata_list:
    hasil += kata + " "   # membuat string baru setiap iterasi

# BENAR: gunakan join()
hasil = " ".join(kata_list)
print(hasil)  # → Python adalah bahasa yang hebat

bool — Boolean #

bool adalah subkelas dari int di Python. True sama dengan 1 dan False sama dengan 0 — ini memungkinkan beberapa trik ringkas tapi juga jadi sumber kebingungan.

print(True + True)    # → 2
print(True * 5)       # → 5
print(False + 1)      # → 1
print(isinstance(True, int))  # → True (bool adalah subkelas int!)

# Nilai truthy dan falsy
# Semua nilai di bawah ini dianggap False saat digunakan dalam kondisi:
falsy_values = [
    False, 0, 0.0, 0j,     # angka nol
    "", '', b"",            # string kosong
    [], (), {},  set(),     # koleksi kosong
    None,                   # None
]

# Semua nilai lain dianggap True
print(bool(42))       # → True
print(bool(-1))       # → True (negatif pun True!)
print(bool(""))       # → False
print(bool("0"))      # → True  (string "0" bukan nol!)
print(bool([]))       # → False
print(bool([0]))      # → True  (list dengan 1 elemen meski nol)
# Memanfaatkan truthy/falsy secara idiomatis
nama = ""

# ANTI-PATTERN: perbandingan eksplisit dengan string kosong
if nama == "":
    print("nama kosong")

# BENAR: cukup evaluasi langsung
if not nama:
    print("nama kosong")

# Contoh lain: cek list kosong
data = []
if not data:
    print("tidak ada data")

None — Tidak Ada Nilai #

None adalah satu-satunya nilai dari tipe NoneType. Digunakan untuk merepresentasikan ketiadaan nilai, mirip dengan null di bahasa lain.

# Penggunaan umum None
def cari_pengguna(user_id):
    # mengembalikan None jika tidak ditemukan
    if user_id not in database:
        return None
    return database[user_id]

hasil = cari_pengguna(999)

# ANTI-PATTERN: membandingkan None dengan ==
if hasil == None:
    print("tidak ditemukan")

# BENAR: selalu gunakan 'is' atau 'is not' untuk None
if hasil is None:
    print("tidak ditemukan")

if hasil is not None:
    print(f"ditemukan: {hasil}")
# None sebagai default parameter (pola umum di Python)
def tambah_ke_list(nilai, target=None):
    # ANTI-PATTERN: menggunakan list sebagai default langsung
    # def tambah_ke_list(nilai, target=[]):  ← BAHAYA! list default dishare antar pemanggilan

    # BENAR: gunakan None sebagai sentinel, buat list baru di dalam fungsi
    if target is None:
        target = []
    target.append(nilai)
    return target

print(tambah_ke_list(1))    # → [1]
print(tambah_ke_list(2))    # → [2]  (list baru, bukan [1, 2]!)

Tipe Koleksi #

list — Koleksi Terurut yang Bisa Diubah #

# Membuat list
angka = [1, 2, 3, 4, 5]
campuran = [42, "hello", 3.14, True, None]   # boleh tipe berbeda
bersarang = [[1, 2], [3, 4], [5, 6]]         # list di dalam list
kosong = []

# Operasi dasar
angka.append(6)          # tambah di akhir → [1,2,3,4,5,6]
angka.insert(0, 0)       # tambah di indeks 0 → [0,1,2,3,4,5,6]
angka.pop()              # hapus & kembalikan elemen terakhir → 6
angka.pop(0)             # hapus & kembalikan elemen indeks 0 → 0
angka.remove(3)          # hapus nilai 3 (kemunculan pertama)
angka.sort()             # urutkan di tempat (in-place)
angka.reverse()          # balik urutan di tempat
print(len(angka))        # → jumlah elemen
print(3 in angka)        # → True/False

tuple — Koleksi Terurut yang Tidak Bisa Diubah #

# Membuat tuple
koordinat = (10.5, -6.2)
rgb = (255, 128, 0)
satu_elemen = (42,)       # koma wajib untuk tuple 1 elemen!
kosong = ()

# JEBAKAN: tuple 1 elemen tanpa koma
bukan_tuple = (42)        # ini int biasa, bukan tuple
print(type(bukan_tuple))  # → <class 'int'>
print(type((42,)))        # → <class 'tuple'>

# Tuple immutable — tidak bisa diubah
koordinat[0] = 99         # TypeError: 'tuple' object does not support item assignment

# Kapan gunakan tuple vs list?
# Tuple: data yang tidak seharusnya berubah (koordinat, RGB, record database)
# List: data yang akan dimodifikasi (keranjang belanja, antrian proses)

dict — Pasangan Kunci-Nilai #

# Membuat dict
pengguna = {
    "nama": "Budi Santoso",
    "umur": 28,
    "email": "[email protected]",
    "aktif": True,
}

# Akses nilai
print(pengguna["nama"])              # → Budi Santoso
print(pengguna.get("telepon"))       # → None (tidak error jika key tidak ada)
print(pengguna.get("telepon", "-"))  # → - (nilai default)

# ANTI-PATTERN: akses langsung tanpa cek
telepon = pengguna["telepon"]        # KeyError jika key tidak ada

# BENAR: gunakan .get() untuk key yang mungkin tidak ada
telepon = pengguna.get("telepon", "tidak tersedia")

# Operasi dict
pengguna["telepon"] = "081234567890"  # tambah/update key
del pengguna["aktif"]                 # hapus key
print("email" in pengguna)            # → True (cek keberadaan key)

# Iterasi
for key in pengguna:
    print(key)

for key, value in pengguna.items():
    print(f"{key}: {value}")

print(list(pengguna.keys()))     # → ['nama', 'umur', 'email', 'telepon']
print(list(pengguna.values()))   # → ['Budi Santoso', 28, '[email protected]', '...']

set — Koleksi Nilai Unik #

# Membuat set
buah = {"apel", "jeruk", "mangga", "apel"}   # duplikat otomatis dihapus
print(buah)   # → {'apel', 'jeruk', 'mangga'} (urutan tidak dijamin)

# set kosong HARUS menggunakan set(), bukan {}
kosong = set()    # ✓ set kosong
bukan_set = {}    # ✗ ini dict kosong, bukan set!

# Operasi himpunan
a = {1, 2, 3, 4, 5}
b = {3, 4, 5, 6, 7}

print(a | b)    # union (gabungan)        → {1,2,3,4,5,6,7}
print(a & b)    # intersection (irisan)   → {3,4,5}
print(a - b)    # difference (selisih)    → {1,2}
print(a ^ b)    # symmetric difference   → {1,2,6,7}

# Penggunaan umum: hapus duplikat dari list
data = [1, 2, 2, 3, 3, 3, 4]
unik = list(set(data))
print(unik)   # → [1, 2, 3, 4] (urutan tidak dijamin)

# Cek keanggotaan — O(1), jauh lebih cepat dari list
print(3 in a)   # → True

Mutable vs Immutable #

Perbedaan ini krusial untuk dipahami — banyak bug tersembunyi berasal dari salah memahami mana yang mutable dan mana yang tidak.

Immutable (tidak bisa diubah):    Mutable (bisa diubah):
─────────────────────────────     ────────────────────────
int, float, complex               list
str                               dict
bool                              set
tuple                             bytearray
frozenset
bytes
# Immutable: operasi menghasilkan objek BARU
s = "hello"
s_baru = s.upper()    # s tidak berubah, s_baru adalah objek baru
print(s)              # → hello
print(s_baru)         # → HELLO

# Mutable: operasi mengubah objek YANG SAMA
lst = [1, 2, 3]
lst.append(4)         # lst dimodifikasi langsung
print(lst)            # → [1, 2, 3, 4]

# Konsekuensi penting: objek mutable tidak bisa dijadikan key dict
d = {}
d[(1, 2)] = "tuple sebagai key"   # ✓ tuple immutable
d[[1, 2]] = "list sebagai key"    # ✗ TypeError: unhashable type: 'list'

Konversi Tipe Data #

Python menyediakan fungsi bawaan untuk konversi eksplisit antar tipe. Penting untuk diingat: tidak semua konversi akan berhasil — beberapa bisa melempar exception.

# int() — konversi ke integer
print(int("42"))        # → 42
print(int(3.99))        # → 3  (dipotong, bukan dibulatkan!)
print(int(True))        # → 1
print(int("0xFF", 16))  # → 255 (string hex ke int)

# Yang akan gagal:
# int("3.14")    → ValueError: invalid literal for int()
# int("hello")   → ValueError

# float() — konversi ke float
print(float("3.14"))    # → 3.14
print(float(42))        # → 42.0
print(float("inf"))     # → inf

# str() — konversi ke string (selalu berhasil)
print(str(42))          # → "42"
print(str(3.14))        # → "3.14"
print(str(True))        # → "True"
print(str(None))        # → "None"
print(str([1, 2, 3]))   # → "[1, 2, 3]"

# bool() — konversi ke boolean
print(bool(0))          # → False
print(bool(""))         # → False
print(bool([]))         # → False
print(bool(42))         # → True
print(bool("false"))    # → True  (string non-kosong selalu True!)

# Konversi koleksi
print(list((1, 2, 3)))       # tuple → list: [1, 2, 3]
print(tuple([1, 2, 3]))      # list → tuple: (1, 2, 3)
print(set([1, 2, 2, 3]))     # list → set:   {1, 2, 3}
print(list("hello"))         # str → list:   ['h','e','l','l','o']
print("".join(['h','i']))    # list → str:   "hi"

Konversi yang Aman dengan Penanganan Error #

def ke_int_aman(nilai, default=0):
    """Konversi ke int tanpa melempar exception."""
    try:
        return int(nilai)
    except (ValueError, TypeError):
        return default

print(ke_int_aman("42"))       # → 42
print(ke_int_aman("abc"))      # → 0 (default)
print(ke_int_aman("abc", -1))  # → -1 (custom default)
print(ke_int_aman(None))       # → 0

Mengecek Tipe Data #

x = 42

# type() — mengembalikan tipe persis
print(type(x))              # → <class 'int'>
print(type(x) == int)       # → True

# isinstance() — cek tipe termasuk subkelas (lebih direkomendasikan)
print(isinstance(x, int))           # → True
print(isinstance(x, (int, float)))  # → True (cek beberapa tipe sekaligus)
print(isinstance(True, int))        # → True (bool adalah subkelas int)

# ANTI-PATTERN: type() untuk cek tipe — tidak mengenali subkelas
print(type(True) == int)    # → False  (meski True adalah subkelas int)

# BENAR: isinstance() untuk cek tipe
print(isinstance(True, int))  # → True

Ringkasan #

  • int tidak terbatas ukurannya — tidak perlu khawatir overflow seperti di C/Java. Python otomatis mengelola memori untuk integer besar.
  • Jangan bandingkan float dengan == — gunakan math.isclose(). Representasi biner float tidak eksak untuk sebagian besar desimal.
  • Jangan gunakan float untuk kalkulasi uang — gunakan decimal.Decimal untuk presisi finansial yang benar.
  • String immutable — setiap operasi string menghasilkan objek baru. Gunakan "".join(list) alih-alih concatenation dalam loop.
  • None selalu dibandingkan dengan is/is not, bukan ==/!=.
  • Set kosong harus set(), bukan {} — kurung kurawal kosong adalah dict kosong.
  • Mutable tidak bisa jadi key dict — gunakan tuple (immutable) sebagai key, bukan list.
  • isinstance() lebih baik dari type() — mengenali subkelas, lebih fleksibel untuk pengecekan tipe.
  • Konversi bool("false") menghasilkan True — string non-kosong apapun adalah truthy, termasuk string "false", "0", dan "None".

← Sebelumnya: Konstanta   Berikutnya: Operator →

About | Author | Content Scope | Editorial Policy | Privacy Policy | Disclaimer | Contact