Saya mulai python dan saya mencoba menggunakan daftar dua dimensi, yang awalnya saya isi dengan variabel yang sama di setiap tempat. Saya datang dengan ini:
def initialize_twodlist(foo):
twod_list = []
new = []
for i in range (0, 10):
for j in range (0, 10):
new.append(foo)
twod_list.append(new)
new = []
Ini memberikan hasil yang diinginkan, tetapi terasa seperti solusi. Apakah ada cara yang lebih mudah / lebih pendek / lebih elegan untuk melakukan ini?
python
multidimensional-array
wajah wajahku
sumber
sumber
Jawaban:
Pola yang sering muncul dalam Python adalah
yang membantu memotivasi pengenalan daftar, yang mengubah cuplikan itu menjadi
yang lebih pendek dan terkadang lebih jelas. Biasanya Anda terbiasa mengenali ini dan sering mengganti loop dengan pemahaman.
Kode Anda mengikuti pola ini dua kali
sumber
[foo] * 10
adalah daftar dengan jumlah persis samafoo
10 kali, yang mungkin atau mungkin tidak penting.[foo] * 10
: Ini berarti bahwa ini tidak akan bekerja jika Anda mengisi array dengan nomor acak (mengevaluasi[random.randint(1,2)] * 10
ke[1] * 10
atau[2] * 10
yang berarti bahwa Anda mendapatkan array dari semua 1s atau 2s, bukan array acak.Anda dapat menggunakan pemahaman daftar :
sumber
i
untuk baris danj
kolom, saya pikir itu harus lebih baik untuk bertukari
danj
dalam sintaks Anda untuk pemahaman yang lebih baik dan mengubah rentang menjadi 2 angka yang berbeda.Jangan gunakan
[[v]*n]*n
, itu jebakan!tapi
bekerja dengan baik.
sumber
*
menyalinaddress
objek (daftar).[[0] * col for _ in range(row)]
,.Cara ini lebih cepat daripada pemahaman daftar bersarang
Berikut adalah beberapa timing python3, untuk daftar kecil dan besar
Penjelasan:
[[foo]*10]*10
membuat daftar objek yang sama diulang 10 kali. Anda tidak bisa hanya menggunakan ini, karena memodifikasi satu elemen akan mengubah elemen yang sama di setiap baris!x[:]
setara denganlist(X)
tetapi sedikit lebih efisien karena menghindari pencarian nama. Either way, itu membuat salinan dangkal setiap baris, jadi sekarang semua elemen independen.Semua elemen adalah
foo
objek yang sama , jadi jikafoo
bisa berubah , Anda tidak dapat menggunakan skema ini., Anda harus menggunakannyaatau dengan asumsi kelas (atau fungsi)
Foo
yang mengembalikanfoo
ssumber
copy.deepcopy
. Anda memerlukan paket khusus untuk data Anda jika Anda memiliki objek yang bisa berubah-ubah.x
dany
. Bukankah seharusnya[[copy.deepcopy(foo) for y in range(10)] for x in range(10)]
[foo]*10
tidak membuat 10 objek berbeda - tetapi mudah untuk mengabaikan perbedaan dalam kasus di mana foo tidak dapat diubah, seperti sebuahint
ataustr
.Untuk menginisialisasi array dua dimensi dengan Python:
sumber
a = [[0 for x in range(columns)] for y in range(rows)]
.sumber
[[0] * col] * row
tidak melakukan apa yang Anda inginkan adalah karena ketika Anda menginisialisasi daftar 2d dengan cara itu, Python tidak akan membuat salinan berbeda dari setiap baris. Sebaliknya itu akan init daftar luar dengan pointer ke salinan yang sama[0]*col
. Hasil edit apa pun yang Anda buat pada salah satu baris akan tercermin dalam baris yang tersisa karena semuanya sebenarnya menunjuk ke data yang sama dalam memori.Biasanya ketika Anda ingin array multidimensi Anda tidak ingin daftar daftar, melainkan array numpy atau mungkin dict.
Misalnya, dengan numpy Anda akan melakukan sesuatu seperti
sumber
numpy
hebat, saya pikir itu mungkin sedikit berlebihan bagi seorang pemula.numpy
. +1Anda dapat melakukan ini:
Sebagai contoh:
Tetapi ini memiliki efek samping yang tidak diinginkan:
sumber
untuk n adalah jumlah baris, dan m adalah jumlah kolom, dan foo adalah nilainya.
sumber
Jika array ini jarang diisi, Anda mungkin lebih baik menggunakan kamus yang dikunci dengan tuple:
sumber
untuk setiap elemen baru
[0]*10
akan dibuat ..sumber
Pendekatan Salah: [[Tidak Ada * m] * n]
Dengan pendekatan ini, python tidak mengizinkan pembuatan ruang alamat yang berbeda untuk kolom luar dan akan menyebabkan berbagai kesalahan perilaku daripada yang Anda harapkan.
Pendekatan yang Benar tetapi dengan pengecualian:
Ini adalah pendekatan yang baik tetapi ada pengecualian jika Anda menetapkan nilai default
None
Jadi atur nilai default Anda dengan benar menggunakan pendekatan ini.
Benar sekali:
Ikuti balasan mike dari loop ganda .
sumber
sumber
Untuk menginisialisasi penggunaan array 2 dimensi:
arr = [[]*m for i in range(n)]
sebenarnya,
arr = [[]*m]*n
akan membuat array 2D di mana semua n array akan menunjuk ke array yang sama, sehingga setiap perubahan nilai dalam elemen apa pun akan tercermin di semua daftar nuntuk penjelasan lebih lanjut, kunjungi: https://www.geeksforgeeks.org/python-using-2d-arrays-lists-the-right-way/
sumber
gunakan pemikiran paling sederhana untuk membuat ini.
dan tambahkan ukuran:
atau jika kita ingin mendeklarasikan ukurannya terlebih dahulu. kami hanya menggunakan:
sumber
Seperti yang ditunjukkan oleh @Arnab dan @Mike, array bukanlah daftar. Beberapa perbedaan adalah 1) array ukuran tetap selama inisialisasi 2) array biasanya mendukung operasi yang lebih rendah daripada daftar.
Mungkin berlebihan dalam banyak kasus, tapi di sini adalah implementasi array 2d dasar yang memanfaatkan implementasi array perangkat keras menggunakan python ctypes (c libraries)
sumber
Yang penting saya mengerti adalah: Ketika menginisialisasi array (dalam dimensi apa pun), kita harus memberikan nilai default untuk semua posisi array. Maka hanya inisialisasi yang selesai. Setelah itu, kami dapat mengubah atau menerima nilai baru ke posisi array apa pun. Kode di bawah ini berfungsi dengan baik untuk saya
sumber
Jika Anda menggunakan numpy , Anda dapat dengan mudah membuat array 2d:
x
sumber
Di atas akan memberi Anda array 2D 5x5
Ini menggunakan pemahaman daftar bersarang. Breakdown seperti di bawah ini:
[x] * col -> ekspresi akhir yang dievaluasi
untuk x in -> x akan menjadi nilai yang diberikan oleh iterator
[b untuk b dalam rentang (baris)]] -> Iterator.
[b untuk b dalam rentang (baris)]] ini akan dievaluasi menjadi [0,1,2,3,4] karena baris = 5
jadi sekarang ia disederhanakan menjadi
Ini akan mengevaluasi ke [[0] * 5 untuk x di [0,1,2,3,4]] -> dengan x = 0 iterasi pertama
[[1] * 5 untuk x di [0,1,2, 3,4]] -> dengan x = 1 iterasi ke 2
[[2] * 5 untuk x di [0,1,2,3,4]] -> dengan x = 2 iterasi ke-3
[[3] * 5 untuk x dalam [0,1,2,3,4]] -> dengan x = 3 iterasi ke 4
[[4] * 5 untuk x dalam [0,1,2,3,4]] -> dengan x = 4 iterasi ke-5
sumber
Ini adalah yang terbaik yang saya temukan untuk mengajar programmer baru, dan tanpa menggunakan perpustakaan tambahan. Saya ingin sesuatu yang lebih baik.
sumber
Ini cara yang lebih mudah:
Untuk menginisialisasi semua sel dengan menggunakan nilai 'x':
sumber
Seringkali saya menggunakan pendekatan ini untuk menginisialisasi array 2 dimensi
n=[[int(x) for x in input().split()] for i in range(int(input())]
sumber
Pola umum untuk menambahkan dimensi dapat diambil dari seri ini:
sumber
Anda dapat mencoba ini [[0] * 10] * 10. Ini akan mengembalikan array 2d dari 10 baris dan 10 kolom dengan nilai 0 untuk setiap sel.
sumber
a = [[0]*10]*10
dan kemudiana[0][0] = 1
Anda akan melihat bahwa elemen pertama di setiap baris sekarang sama dengan 1lst = [[0] * m untuk saya dalam kisaran (n)]
inisialisasi semua matriks n = baris dan m = kolom
sumber
Cara lain adalah dengan menggunakan kamus untuk memegang array dua dimensi.
Ini hanya dapat menampung 1D, nilai 2D dan untuk menginisialisasi ini ke
0
atau nilai int lainnya, gunakan koleksi .sumber
Kode:
initial_val
harus kekal.sumber
sumber