List Python adalah wadah paling serbaguna di bahasa ini: satu list boleh berisi integer, string, bahkan list lain sekaligus, dan isinya dapat ditambah atau dibuang kapan saja. Keluwesan itu layak dimiliki saat data sedikit. Namun pada komputasi numerik, fleksibilitas list justru menjadi beban: setiap elemen adalah objek Python penuh yang diawasi interpreter.
ndarray NumPy mengambil jalan sebaliknya — kaku tetapi cepat. Bab ini membandingkan keduanya pada empat aspek (tipe data, aritmatika, memori, dan kerja di balik layar), lalu menutup dengan panduan kapan list masih menjadi pilihan yang tepat.
Perbandingan Singkat #
| Aspek | Python list | ndarray NumPy |
|---|---|---|
| Tipe elemen | heterogen, tiap elemen bebas bertipe | homogen, satu dtype untuk semua elemen |
| Struktur memori | wadah pointer menuju objek terpisah | satu buffer kontinu berisi nilai mentah |
| Aritmatika | perlu loop atau comprehension manual | ekspresi langsung, misalnya harga * 1.1 |
| Kecepatan | operasi ditafsirkan per objek oleh interpreter | operasi dijalankan sekali di kode C |
| Ukuran memori | besar: pointer plus objek per elemen | kecil: nilai mentah berdempetan |
| Struktur | bersarang bebas, dimensi boleh campur | bentuk tetap (shape), perubahan dimensi eksplisit |
Dua aspek pertama — tipe dan memori — menjadi akar penyebab perbedaan sisanya. Mari kita bedah satu per satu dengan bukti kode.
Aritmatika per Elemen: Loop vs Ekspresi #
Misalkan harga tiga barang naik 10 persen dan hasilnya perlu dibulatkan ke rupiah penuh. Versi list memaksa kita menulis comprehension; versi array cukup satu ekspresi:
import numpy as np
harga_list = [15000, 24000, 8000]
harga_np = np.array(harga_list)
naik_list = [round(h * 1.1) for h in harga_list]
naik_np = np.round(harga_np * 1.1)
print(naik_list)
print(naik_np)Output yang Dihasilkan:
[16500, 26400, 8800]
[16500. 26400. 8800.]Mari kita amati per baris:
- Baris 3-4:
harga_npdibuat dari list yang sama, sehingga kedua versi bekerja pada data yang identik. - Baris 6 (list): comprehension mengulang elemen satu per satu di level Python;
round(h * 1.1)dijalankan tiga kali terpisah. - Baris 7 (array):
harga_np * 1.1mengalikan seluruh elemen sekaligus di kode C, lalunp.roundmembulatkan hasilnya. Satu ekspresi menggantikan seluruh loop. - Output: nilai keduanya sama; tanda titik pada array hanya menandakan tipenya
float64.
Nilai 1.1 tidak persis terwakili di sistem biner, sehingga hasil kali mentahnya bisa berupa pecahan panjang seperti 16500.000000000002. Karena konteksnya rupiah, kita bulatkan dengan round dan np.round — sekaligus membuat perbandingan kedua output menjadi ringkas.
Penggunaan Memori #
Cara paling jujur membandingkan memori adalah mengukurnya langsung: sys.getsizeof untuk list dan atribut nbytes milik ndarray.
import numpy as np
import sys
data_list = list(range(256, 1256)) # 1000 bilangan bulat unik
data_np = np.arange(256, 1256)
total_list = sys.getsizeof(data_list) + sum(sys.getsizeof(x) for x in data_list)
print("Python list :", total_list, "byte")
print("NumPy int64 :", data_np.nbytes, "byte")Output yang Dihasilkan:
Python list : 36056 byte
NumPy int64 : 8000 byteAngka list dihitung dua lapis agar pengukurannya adil. sys.getsizeof(data_list) hanya mengukur wadah pointer (1000 pointer × 8 byte + header 56 byte), sedangkan setiap objek integer menempati ±28 byte di lokasi memori lain; jumlah keduanya menghasilkan 36056 byte. ndarray tidak mengalami pembengkakan itu: nbytes menunjukkan 1000 elemen × 8 byte per int64 = 8000 byte dalam satu blok. Selisih sekitar 4,5 kali ini membesar seiring jumlah data.
Rentang 256 ke atas dipilih dengan sengaja: CPython meng-cache bilangan kecil dari -5 sampai 256, sehingga bilangan di luar rentang itu membuat ukuran tiap objek konsisten dan hasil pengukuran dapat direproduksi.
Tipe Homogen vs Heterogen #
Perbedaan tipe paling terasa saat data campuran masuk. List menyimpan apa adanya; ndarray memaksa semuanya menyatu ke satu dtype:
import numpy as np
data_np = np.array([90, "Budi", 85.5])
print(data_np.dtype)
print(data_np)Output yang Dihasilkan:
<U32
['90' 'Budi' '85.5']Ketiga nilai dipaksa menjadi teks: tipe <U32 adalah string Unicode berlebar tetap, dan angka 90 serta 85.5 kehilangan sifat numeriknya — menghitung data_np.mean() menjadi tidak mungkin. List Python tidak mengalami masalah semacam ini karena setiap elemennya memang objek bebas.
Kapan List Tetap Pilihan Tepat #
- Data hanya sedikit (puluhan elemen) dan dihitung sesekali.
- Elemen campur tipe atau berstruktur bertingkat, misalnya list of dict.
- Butuh pertumbuhan dinamis:
appenddanremovesaat program berjalan. - Mengumpulkan hasil secara bertahap, lalu mengonversi sekali dengan
np.array(...)di akhir.
List dan array bukan saingan yang saling menggantikan; keduanya saling melengkapi. Pola umum di lapangan: kumpulkan data dengan list, lalu olah bagian beratnya di array. Panduan keputusan lengkapnya kita rangkum pada bab Kapan Menggunakan NumPy.