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:

python
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:

text
[15000 27500 12000] int64
asarray dari list -> False
asarray dari array -> True

Mari kita bedah:

  1. Baris 3-4 (np.array(harga)): interpreter membaca list berisi objek int Python, mengalokasikan buffer int64 yang baru, lalu menyalin setiap nilai ke dalamnya. Variabel a tidak berbagi apa pun dengan list harga.
  2. Baris 6-7 (np.asarray(harga)): list tidak punya buffer memori yang bisa dipinjam, sehingga np.asarray pun harus membuat array baru; hasilnya False terhadap np.shares_memory.
  3. Baris 8-9 (np.asarray(a)): input berupa ndarray yang sudah tepat, sehingga np.asarray mengembalikan 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:

python
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:

text
[[2, 5], [7, 3]] <class 'list'>
<class 'int'>
identik -> True
memori sama -> False

Penjelasan tiap baris:

  1. Baris 3: array stok bertipe int64 berbentuk (2, 2).
  2. Baris 4-6 (stok.tolist()): tolist() menghasilkan list bersarang [[2, 5], [7, 3]]; pemeriksaan type(lst[0][0]) membuktikan elemennya int Python, bukan tipe NumPy.
  3. Baris 7-9: np.array(lst) membangun kembali array dengan nilai identik, namun np.shares_memory bernilai False — 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:

python
import numpy as np

data = [[1, 2, 3], [4, 5]]
try:
    np.array(data)
except ValueError as e:
    print("ValueError:", e)

Output yang Dihasilkan:

text
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:

  1. Baris 3: data berisi dua list dengan panjang berbeda, yaitu 3 dan 2; tidak ada panjang seragam yang bisa menjadi jumlah kolom.
  2. Baris 4-7 (try/except): interpreter menilai bentuknya tidak bisa diseragamkan, lalu melempar ValueError dengan 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:

python
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:

text
list : 32856 byte
array: 8000 byte
rasio ~ 4

Bedah singkat:

  1. Baris 5: list berisi 1000 objek float; masing-masing objek berdiri sendiri di memori dan list menambahkan satu pointer per elemen.
  2. Baris 6: total memori dihitung jujur dua lapis — wadah list (856 byte pointer) ditambah seluruh objek float-nya (32000 byte).
  3. Baris 7-9: array float64 menyimpan 1000 nilai berturutan dalam 8000 byte; perbandingannya sekitar empat kali lebih hemat.
Aspeklist Pythonndarray
Tipe elemenbebas bercampursatu dtype untuk semua
Memori per elemenobjek + pointernilai mentah yang padat
Operasi numerikloop manualvectorization
Menambah/menghapus elemenfleksibel (append, pop)perlu membuat array baru
Tempat paling pasdata kecil, heterogen, atau bertingkatdata 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.