Sebagian besar data di dalam script Python kita lahir sebagai list: hasil pembacaan file, output dari loop, atau data yang diketik langsung di dalam kode. Karena itu, jembatan antara list dan ndarray adalah jalur interoperabilitas yang paling sering kita lewati. Bab ini merapikan dua arah jalur tersebut — dari list ke array dengan np.array, dan dari array kembali ke list dengan tolist() — beserta konsekuensi salin-menyalin memori yang menyertai setiap konversi.
Kita juga membahas satu perubahan perilaku penting di NumPy 2: list bersarang yang tidak seragam kini ditolak dengan ValueError, bukan sekadar diberi peringatan seperti di NumPy 1.x. Di akhir bab, sebuah tabel dan daftar singkat membantu kita memutuskan kapan list masih wajar dipakai dan kapan sebaiknya data dipindah ke array.
Dari List ke ndarray #
Fungsi np.array membaca list level demi level, memeriksa tipe setiap elemen, lalu menyusun buffer numerik yang padat. Hasilnya selalu array baru di memori yang terpisah dari list asalnya. Untuk melihat konsekuensinya, kita bandingkan np.array dengan np.asarray pada dua jenis input:
import numpy as np
harga = [15000, 27500, 12000]
a = np.array(harga)
print(a, a.dtype)
b = np.asarray(harga)
print("asarray dari list ->", np.shares_memory(a, b))
c = np.asarray(a)
print("asarray dari array ->", np.shares_memory(a, c))Output yang Dihasilkan:
[15000 27500 12000] int64
asarray dari list -> False
asarray dari array -> TrueMari kita bedah:
- Baris 3-4 (
np.array(harga)): interpreter membaca list berisi objekintPython, mengalokasikan bufferint64yang baru, lalu menyalin setiap nilai ke dalamnya. Variabelatidak berbagi apa pun dengan listharga. - Baris 6-7 (
np.asarray(harga)): list tidak punya buffer memori yang bisa dipinjam, sehingganp.asarraypun harus membuat array baru; hasilnyaFalseterhadapnp.shares_memory. - Baris 8-9 (
np.asarray(a)): input berupa ndarray yang sudah tepat, sehingganp.asarraymengembalikan objek yang sama tanpa menyalin —True.
Kesimpulannya: konversi list ke array selalu menyalin data, sedangkan np.asarray pada ndarray berjalan tanpa salinan. Jika kode kita menerima “array atau list”, gunakan np.asarray agar jalur array tidak kena biaya salin ganda.
Kembali ke List dengan tolist() #
Method tolist() adalah pintu keluar resmi dari array. Method ini menelusuri seluruh dimensi array dan menghasilkan list bersarang yang berisi objek Python asli — bukan np.int64 atau np.float64:
import numpy as np
stok = np.array([[2, 5], [7, 3]])
lst = stok.tolist()
print(lst, type(lst))
print(type(lst[0][0]))
kembali = np.array(lst)
print("identik ->", np.array_equal(stok, kembali))
print("memori sama ->", np.shares_memory(stok, kembali))Output yang Dihasilkan:
[[2, 5], [7, 3]] <class 'list'>
<class 'int'>
identik -> True
memori sama -> FalsePenjelasan tiap baris:
- Baris 3: array
stokbertipeint64berbentuk(2, 2). - Baris 4-6 (
stok.tolist()):tolist()menghasilkan list bersarang[[2, 5], [7, 3]]; pemeriksaantype(lst[0][0])membuktikan elemennyaintPython, bukan tipe NumPy. - Baris 7-9:
np.array(lst)membangun kembali array dengan nilai identik, namunnp.shares_memorybernilaiFalse— buffer lamanya sudah tidak dipakai; dua konversi ini bersifat salin total.
List Bersarang Tidak Seragam Kini Ditandai Error #
List bersarang yang jumlah elemennya berbeda antar baris — misalnya data transaksi yang satu barisnya lengkap dan yang lain terpotong — dulu masih bisa dikonversi di NumPy 1.x dengan peringatan. NumPy 2 menolaknya langsung:
import numpy as np
data = [[1, 2, 3], [4, 5]]
try:
np.array(data)
except ValueError as e:
print("ValueError:", e)Output yang Dihasilkan:
ValueError: setting an array element with a sequence. The requested array has an inhomogeneous shape after 1 dimensions. The detected shape was (2,) + inhomogeneous part.Yang terjadi di balik layar:
- Baris 3:
databerisi dua list dengan panjang berbeda, yaitu 3 dan 2; tidak ada panjang seragam yang bisa menjadi jumlah kolom. - Baris 4-7 (
try/except): interpreter menilai bentuknya tidak bisa diseragamkan, lalu melemparValueErrordengan pesan inhomogeneous shape; kita mencetak pesan itu agar script tetap berjalan.
Kapan List Masih Cukup #
Perbedaan paling terasa ada pada memori. List Python menyimpan pointer ke objek terpisah, sedangkan array menyimpan nilai mentah berdempetan:
import numpy as np
import sys
n = 1000
lst = [i + 0.5 for i in range(n)]
memori_list = sys.getsizeof(lst) + sum(sys.getsizeof(v) for v in lst)
a = np.array(lst)
print("list :", memori_list, "byte")
print("array:", a.nbytes, "byte")
print("rasio ~", round(memori_list / a.nbytes))Output yang Dihasilkan:
list : 32856 byte
array: 8000 byte
rasio ~ 4Bedah singkat:
- Baris 5: list berisi 1000 objek
float; masing-masing objek berdiri sendiri di memori dan list menambahkan satu pointer per elemen. - Baris 6: total memori dihitung jujur dua lapis — wadah list (856 byte pointer) ditambah seluruh objek float-nya (32000 byte).
- Baris 7-9: array
float64menyimpan 1000 nilai berturutan dalam 8000 byte; perbandingannya sekitar empat kali lebih hemat.
| Aspek | list Python | ndarray |
|---|---|---|
| Tipe elemen | bebas bercampur | satu dtype untuk semua |
| Memori per elemen | objek + pointer | nilai mentah yang padat |
| Operasi numerik | loop manual | vectorization |
| Menambah/menghapus elemen | fleksibel (append, pop) | perlu membuat array baru |
| Tempat paling pas | data kecil, heterogen, atau bertingkat | data numerik besar yang sering dihitung |
Sebagai penutup, dua pedoman singkat: pertahankan list ketika data sedikit, jenisnya campuran, atau strukturnya berubah-ubah saat program berjalan; pindahkan ke array segera setelah kita perlu menghitung — pembahasan Array dari Python List mengulang konversi ini dari sisi dasar-dasar array, dan bab NumPy vs Python List membandingkan keduanya secara menyeluruh.