Cara mendefinisikan array dua dimensi dengan Python


724

Saya ingin mendefinisikan array dua dimensi tanpa panjang yang diinisialisasi seperti ini:

Matrix = [][]

tapi itu tidak berhasil ...

Saya sudah mencoba kode di bawah ini, tetapi juga salah:

Matrix = [5][5]

Kesalahan:

Traceback ...

IndexError: list index out of range

Apa kesalahan saya?


14
Seseorang tidak mendefinisikan array , atau hal lainnya. Namun, Anda dapat membuat urutan multidimensi, seperti yang ditunjukkan oleh jawaban di sini. Ingat bahwa variabel python tidak diketik , tetapi nilainya diketik dengan kuat.
SingleNegationElimination

1
Saya bingung. Berasal dari bahasa lain: ADALAH perbedaan antara Array 1D yang berisi Array 1D dan Array 2D. Dan AFAIK tidak mungkin memiliki multi-dimensional-array (atau daftar) dalam python. Harus dikatakan di sini ...
Dirk Reichel

Jawaban:


1009

Secara teknis Anda mencoba mengindeks array yang tidak diinisialisasi. Anda harus terlebih dahulu menginisialisasi daftar luar dengan daftar sebelum menambahkan item; Python menyebut ini "daftar pemahaman".

# Creates a list containing 5 lists, each of 8 items, all set to 0
w, h = 8, 5;
Matrix = [[0 for x in range(w)] for y in range(h)] 

Anda sekarang dapat menambahkan item ke daftar:

Matrix[0][0] = 1
Matrix[6][0] = 3 # error! range... 
Matrix[0][6] = 3 # valid

Perhatikan bahwa matriksnya adalah "y" address major, dengan kata lain, "y index" muncul sebelum "x index".

print Matrix[0][0] # prints 1
x, y = 0, 6 
print Matrix[x][y] # prints 3; be careful with indexing! 

Meskipun Anda dapat menamai mereka seperti yang Anda inginkan, saya melihatnya dengan cara ini untuk menghindari kebingungan yang dapat timbul dengan pengindeksan, jika Anda menggunakan "x" untuk daftar dalam dan luar, dan ingin Matriks non-persegi.


219
[[0 untuk x dalam rentang (cols_count)] untuk x dalam kisaran (rows_count)]
songhir

3
Sunting aneh oleh ademar111190. Dalam Python 3 tidak ada xrange tetapi jika Anda harus menggunakan Python 2 maka xrange adalah fungsi yang benar untuk digunakan jika Anda tidak ingin membuat objek secara sia-sia.
Dave

4
@dave Jika Anda tidak memerlukannya nol-diisi, dapat digunakan rangeuntuk membuat daftar internal secara langsung:[range(5) for x in range(5)]
alanjds

2
@alanjds - itu benar, tetapi Anda masih berpotensi membuat banyak referensi objek yang tidak perlu dalam Python 2 untuk iterasi luar (coba ini dengan rentang yang SANGAT besar). Juga, inisialisasi ke beberapa nilai hampir selalu seperti yang Anda inginkan - dan ini lebih sering daripada rentang 0. menghasilkan koleksi yang dapat diubah - xrange mengembalikan generator. Maksud saya adalah bahwa ademar "mengoreksi" sesuatu yang sebenarnya lebih umum benar dan efisien daripada koreksinya.
Dave

10
@ 6paket [0] * wbagian itu bagus, tetapi [[0] * w] * h]akan menghasilkan perilaku yang tidak terduga. Coba mat = [[0] * 3] * 3; mat[0][1] = 10; print(mat == [[0, 10, 0], [0, 10, 0], [0, 10, 0]])dan mat = [[0] * 3 for i in range(3)]; mat[0][1] = 10; print(mat == [[0, 10, 0], [0, 0, 0], [0, 0, 0]]).
pengirim

408

Jika Anda benar-benar menginginkan sebuah matriks, Anda mungkin lebih baik menggunakan numpy. Operasi matriks di numpypaling sering menggunakan tipe array dengan dua dimensi. Ada banyak cara untuk membuat array baru; salah satu yang paling berguna adalah zerosfungsi, yang mengambil parameter bentuk dan mengembalikan array bentuk yang diberikan, dengan nilai yang diinisialisasi ke nol:

>>> import numpy
>>> numpy.zeros((5, 5))
array([[ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

Berikut adalah beberapa cara lain untuk membuat array dan matriks 2-d (dengan output dihapus untuk kekompakan):

numpy.arange(25).reshape((5, 5))         # create a 1-d range and reshape
numpy.array(range(25)).reshape((5, 5))   # pass a Python range and reshape
numpy.array([5] * 25).reshape((5, 5))    # pass a Python list and reshape
numpy.empty((5, 5))                      # allocate, but don't initialize
numpy.ones((5, 5))                       # initialize with ones

numpymenyediakan matrixjenis juga, tetapi tidak lagi direkomendasikan untuk penggunaan apa pun , dan dapat dihapus dari numpydi masa depan.


80
Setiap kali Anda ingin matriks, Anda ingin menggunakan numpy. Jawaban ini harus menjadi yang pertama.
Pat B

3
Fakta bahwa pertanyaan menggunakan kata "matrix" dalam bahasa Inggris tidak berarti bahwa mereka harus menggunakannya np.matrixuntuk mewakilinya. Cara yang tepat untuk merepresentasikan matriks dalam numpy adalah dengan array.
user2357112 mendukung Monica

@ user2357112, Dan seperti yang Anda lihat, sebagian besar contoh yang tercantum di atas adalah keluaran arraybukan matriks. Meskipun tidak selalu dianjurkan, ada alasan yang sah untuk menggunakan matrixhal-hal konteks.
pengirim

1
@senderle, Bisakah Anda memperluas alasan penggunaan matrix? Sejak @operator diperkenalkan, sepertinya ada satu alasan lebih sedikit sejak tulisan ini ditulis.
jpp

1
@jpp, seperti yang dikatakan sebelumnya, orang-orang yang datang dari matlab mungkin merasa berguna. Tetapi numpydokumen sekarang menunjukkan bahwa kelas mungkin sudah usang dan dihapus di masa depan, jadi saya sudah mengeluarkannya dari jawabannya.
pengirim

337

Berikut adalah notasi yang lebih singkat untuk menginisialisasi daftar daftar:

matrix = [[0]*5 for i in range(5)]

Sayangnya memperpendek ini menjadi sesuatu seperti 5*[5*[0]]tidak benar-benar berfungsi karena Anda berakhir dengan 5 salinan dari daftar yang sama, jadi ketika Anda memodifikasi salah satu dari mereka semuanya berubah, misalnya:

>>> matrix = 5*[5*[0]]
>>> matrix
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
>>> matrix[4][4] = 2
>>> matrix
[[0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2], [0, 0, 0, 0, 2]]

4
Bisakah Anda menjelaskan logika di balik kegagalan "pemendekan"? Mengapa python mengeluarkan salinan dari daftar yang sama dalam kasus ini, dan berbagai sel yang berbeda dalam kasus ini [0]*5?
mike622867

12
Komentar di atas tidak sepenuhnya benar: [0] * 5 masih membuat urutan dengan 5 kali referensi ke Objek yang sama yang mewakili angka 0. Tetapi Anda tidak akan pernah melihat ini karena 0 tidak dapat diubah (saya akan mengatakan 0 berperilaku seperti nilai - atau Anda mungkin menganggapnya sebagai tipe data primitif - karena tidak dapat diubah sehingga Anda tidak pernah mendapatkan masalah dengan referensi ke objek yang sama alih-alih memiliki salinan.)
dreua

4
lebih pythonic: [[0]*5 for _ in range(5)]dengan penghitung loop anonim yang tidak Anda gunakan
Jean-François Fabre

Bagus bahwa Anda menunjukkan masalah salinan dangkal pada contoh kedua.
whatacold

terima kasih @dreua, saya benar-benar bingung bagaimana cara [0]*5kerjanya. Sekarang saya mengerti mengapa [{0}]*8itu adalah ide yang buruk juga.
kuku

110

Jika Anda ingin membuat matriks kosong, sintaks yang benar adalah

matrix = [[]]

Dan jika Anda ingin menghasilkan matriks ukuran 5 diisi dengan 0,

matrix = [[0 for i in xrange(5)] for i in xrange(5)]

@ KorayTugay Karena matriks direpresentasikan menggunakan daftar Python (baris) yang bersarang di dalam daftar lain (kolom).
syarat

2
Untuk Python-3 gunakan fungsi rentang bukan fungsi xrange
Rakesh Chaudhari

76

Jika yang Anda inginkan adalah wadah dua dimensi untuk menampung beberapa elemen, Anda bisa menggunakan kamus sebagai gantinya:

Matrix = {}

Maka Anda dapat melakukan:

Matrix[1,2] = 15
print Matrix[1,2]

Ini berhasil karena 1,2 merupakan tupel, dan Anda menggunakannya sebagai kunci untuk mengindeks kamus. Hasilnya mirip dengan matriks jarang bodoh.

Seperti yang ditunjukkan oleh osa dan Josap Valls, Anda juga dapat menggunakan Matrix = collections.defaultdict(lambda:0)sehingga elemen yang hilang memiliki nilai default0 .

Vatsal lebih lanjut menunjukkan bahwa metode ini mungkin tidak sangat efisien untuk matriks besar dan hanya boleh digunakan di bagian kode yang tidak terlalu penting untuk kinerja.


2
Kemudian Anda juga dapat melakukan import collections; Matrix = collections.defaultdict(float), untuk mengganti nol untuk elemen yang tidak diinisialisasi.
Osa

2
Tidak akan mengakses dict untuk tuple (1,2) sebagai kunci memiliki kompleksitas kasus terburuk O (n). Secara internal itu akan hash tuple. Sedangkan menggunakan array 2D akan memberikan O (1) kompleksitas waktu untuk mengakses indeks [1,2] akses. Jadi menggunakan dict untuk ini seharusnya bukan pilihan yang baik.
Vatsal

@Vatsal wiki.python.org/moin/TimeComplexity mengatakan bahwa case rata-rata adalah O (1), tetapi Anda benar tentang case terburuk. Lagi pula, kecuali jika Anda berbicara tentang BANYAK ITEM Anda tidak akan peduli tentang perbedaan ini. Sebagai soal fakta, saya akan lebih khawatir tentang memori daripada waktu akses.
enobayram

Kami juga selalu berusaha menghindari penggunaan dicts hingga kompleksitas keseluruhan algoritme sama atau lebih besar dari O (n ^ 2). Sebagai 'n' kali O (n) akses akan memberikan kompleksitas O (n ^ 2).
Vatsal

@ enobayram, Maaf tapi saya tidak setuju. Analisis asimptotik akan selalu memberikan O (n ^ 2), jika kasus terburuk O (n) akses dilakukan 'n' kali. Sedangkan analisis Amortisasi dapat memberikan batasan yang lebih kecil. Dan ada perbedaan besar antara kasus diamortisasi dan rata-rata ... silakan merujuk sebelum membuat asumsi dan komentar yang tidak jelas
Vatsal

42

Dengan Python Anda akan membuat daftar daftar. Anda tidak harus mendeklarasikan dimensi sebelumnya, tetapi Anda bisa. Sebagai contoh:

matrix = []
matrix.append([])
matrix.append([])
matrix[0].append(2)
matrix[1].append(3)

Sekarang matriks [0] [0] == 2 dan matriks [1] [0] == 3. Anda juga dapat menggunakan sintaksis pemahaman daftar. Contoh ini menggunakannya dua kali lipat untuk membangun "daftar dua dimensi":

from itertools import count, takewhile
matrix = [[i for i in takewhile(lambda j: j < (k+1) * 10, count(k*10))] for k in range(10)]

6
extendjuga akan membantu dalam kasus pertama: Jika Anda mulai dengan m = [[]], maka Anda dapat menambahkan ke daftar dalam (memperpanjang baris) dengan m[0].extend([1,2]), dan menambahkan ke daftar luar (menambahkan baris baru) dengan m.append([3,4]), operasi-operasi itu akan meninggalkan Anda [[1, 2], [3, 4]].
askewchan

22

Jawaban yang diterima baik dan benar, tetapi butuh beberapa saat untuk memahami bahwa saya juga bisa menggunakannya untuk membuat array yang benar-benar kosong.

l =  [[] for _ in range(3)]

hasil dalam

[[], [], []]

22

Anda harus membuat daftar daftar, dan cara terbaik adalah dengan menggunakan pemahaman bersarang:

>>> matrix = [[0 for i in range(5)] for j in range(5)]
>>> pprint.pprint(matrix)
[[0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0]]

Pada [5][5]contoh Anda, Anda membuat daftar dengan bilangan bulat "5" di dalamnya, dan mencoba mengakses item ke-5, dan itu secara alami meningkatkan IndexError karena tidak ada item ke-5:

>>> l = [5]
>>> l[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Sebenarnya urutan untuk row_index ('i') dan column_index ('j') adalah sebagai berikut: '>>> matrix = [[0 untuk column_index dalam range (5)] untuk row_index dalam range (5)]'
Aniruddha Kalburgi

22
rows = int(input())
cols = int(input())

matrix = []
for i in range(rows):
  row = []
  for j in range(cols):
    row.append(0)
  matrix.append(row)

print(matrix)

Mengapa kode yang begitu panjang, itu juga di PythonAnda bertanya?

Dulu ketika saya merasa tidak nyaman dengan Python, saya melihat jawaban baris tunggal untuk menulis matriks 2D dan berkata pada diri sendiri saya tidak akan menggunakan matriks 2-D dalam Python lagi. (Baris tunggal itu sangat menakutkan dan tidak memberi saya informasi tentang apa yang Python lakukan. Juga perhatikan bahwa saya tidak mengetahui steno ini.)

Bagaimanapun, inilah kode untuk pemula yang berasal dari latar belakang C, CPP dan Java

Catatan untuk Python Lovers and Experts: Tolong jangan turun memilih hanya karena saya menulis kode rinci.


13

Menulis ulang agar mudah dibaca:

# 2D array/ matrix

# 5 rows, 5 cols
rows_count = 5
cols_count = 5

# create
#     creation looks reverse
#     create an array of "cols_count" cols, for each of the "rows_count" rows
#        all elements are initialized to 0
two_d_array = [[0 for j in range(cols_count)] for i in range(rows_count)]

# index is from 0 to 4
#     for both rows & cols
#     since 5 rows, 5 cols

# use
two_d_array[0][0] = 1
print two_d_array[0][0]  # prints 1   # 1st row, 1st col (top-left element of matrix)

two_d_array[1][0] = 2
print two_d_array[1][0]  # prints 2   # 2nd row, 1st col

two_d_array[1][4] = 3
print two_d_array[1][4]  # prints 3   # 2nd row, last col

two_d_array[4][4] = 4
print two_d_array[4][4]  # prints 4   # last row, last col (right, bottom element of matrix)

13

Menggunakan:

matrix = [[0]*5 for i in range(5)]

* 5 untuk dimensi pertama berfungsi karena pada level ini data tidak dapat diubah.


5
Saya mungkin akan menulis ini sebagaimatrix = [[0]*cols for _ in range(rows)]
Shital Shah

12

Untuk mendeklarasikan matriks nol (satu):

numpy.zeros((x, y))

misalnya

>>> numpy.zeros((3, 5))
    array([[ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.]])

atau numpy.ones ((x, y)) mis

>>> np.ones((3, 5))
array([[ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.],
   [ 1.,  1.,  1.,  1.,  1.]])

Bahkan tiga dimensi dimungkinkan. ( http://www.astro.ufl.edu/~warner/prog/python.html lihat -> array multi dimensi)


12

Ini adalah bagaimana saya biasanya membuat array 2D dengan python.

col = 3
row = 4
array = [[0] * col for _ in range(row)]

Saya menemukan sintaks ini mudah diingat dibandingkan dengan menggunakan dua untuk loop dalam pemahaman daftar.


11

Saya menggunakan skrip Python pertama saya, dan saya sedikit bingung dengan contoh matriks kuadrat jadi saya harap contoh di bawah ini akan membantu Anda menghemat waktu:

 # Creates a 2 x 5 matrix
 Matrix = [[0 for y in xrange(5)] for x in xrange(2)]

maka

Matrix[1][4] = 2 # Valid
Matrix[4][1] = 3 # IndexError: list index out of range

10

Menggunakan NumPy Anda dapat menginisialisasi matriks kosong seperti ini:

import numpy as np
mm = np.matrix([])

Dan kemudian menambahkan data seperti ini:

mm = np.append(mm, [[1,2]], axis=1)

apa yang akan menjadi pro dan kontra dari menggunakan numpy daripada "daftar pemahaman"?
Revolusi untuk Monica

7

Saya membaca dalam file yang dipisahkan koma seperti ini:

data=[]
for l in infile:
    l = split(',')
    data.append(l)

Daftar "data" kemudian daftar daftar dengan data indeks [baris] [col]


7

Jika Anda ingin dapat menganggapnya sebagai array 2D daripada dipaksa untuk berpikir dalam hal daftar daftar (jauh lebih alami menurut saya), Anda dapat melakukan hal berikut:

import numpy
Nx=3; Ny=4
my2Dlist= numpy.zeros((Nx,Ny)).tolist()

Hasilnya adalah daftar (bukan array NumPy), dan Anda dapat menimpa posisi individu dengan angka, string, apa pun.


adalah numpy.matrixsetara dengan numpy.zerostanpa nol tanpa daftar?
Revolusi untuk Monica

6

Untuk itulah kamus dibuat!

matrix = {}

Anda dapat menentukan kunci dan nilai dengan dua cara:

matrix[0,0] = value

atau

matrix = { (0,0)  : value }

Hasil:

   [ value,  value,  value,  value,  value],
   [ value,  value,  value,  value,  value],
   ...

6

Menggunakan:

import copy

def ndlist(*args, init=0):
    dp = init
    for x in reversed(args):
        dp = [copy.deepcopy(dp) for _ in range(x)]
    return dp

l = ndlist(1,2,3,4) # 4 dimensional list initialized with 0's
l[0][1][2][3] = 1

Saya pikir NumPy adalah cara untuk pergi. Di atas adalah yang umum jika Anda tidak ingin menggunakan NumPy.


Saya suka upaya ini dalam melakukan sesuatu yang sederhana dengan vanilla Python tanpa harus menggunakan numpy.
Rick Henderson

4

dengan menggunakan daftar:

matrix_in_python  = [['Roy',80,75,85,90,95],['John',75,80,75,85,100],['Dave',80,80,80,90,95]]

dengan menggunakan dict: Anda juga dapat menyimpan info ini di tabel hash untuk pencarian cepat seperti

matrix = { '1':[0,0] , '2':[0,1],'3':[0,2],'4' : [1,0],'5':[1,1],'6':[1,2],'7':[2,0],'8':[2,1],'9':[2,2]};

matrix ['1'] akan memberi Anda hasil dalam O (1) waktu

* nb : Anda harus berurusan dengan tabrakan di tabel hash


4

Jika Anda tidak memiliki informasi ukuran sebelum memulai, buat dua daftar satu dimensi.

list 1: To store rows
list 2: Actual two-dimensional matrix

Simpan seluruh baris dalam daftar 1. Setelah selesai, tambahkan daftar 1 ke daftar 2:

from random import randint

coordinates=[]
temp=[]
points=int(raw_input("Enter No Of Coordinates >"))
for i in range(0,points):
    randomx=randint(0,1000)
    randomy=randint(0,1000)
    temp=[]
    temp.append(randomx)
    temp.append(randomy)
    coordinates.append(temp)

print coordinates

Keluaran:

Enter No Of Coordinates >4
[[522, 96], [378, 276], [349, 741], [238, 439]]

3
# Creates a list containing 5 lists initialized to 0
Matrix = [[0]*5]*5

Hati-hati dengan ungkapan singkat ini, lihat penjelasan lengkap di jawaban @ FJ


19
Hati-hati dengan cara ini, karena Matrix[0], Matrix[1], ..., Matrix[4]semua menunjuk ke array yang sama, jadi setelah itu Matrix[0][0] = 3, Anda harapkan Matrix[0][0] == Matrix[1][0] == ... == Matrix[4][0] == 3.
gongzhitaao

1
Terima kasih gongzhitaao untuk komentar Anda. Seandainya saya membacanya elier itu akan menyelamatkan saya setidaknya setengah jam .. Memiliki matriks di mana setiap baris menunjuk ke tempat yang sama dalam memori tampaknya tidak terlalu berguna, dan jika Anda tidak menyadari apa yang Anda lakukan itu bahkan berbahaya! Saya cukup yakin ini BUKAN apa yang ingin dilakukan oleh Masoud Abasian, yang mengajukan pertanyaan.
Adrian

7
Anda harus menghapus jawaban ini, karena itu bukan jawaban yang benar. Pemula mungkin bingung.
cxxl

2
Apa jawaban yang Anda maksud? Saya tidak melihat pengguna dengan nama "FJ" (bahkan tidak dalam jawaban yang dihapus).
Peter Mortensen

3
l=[[0]*(L) for _ in range(W)]

Akan lebih cepat dari:

l = [[0 for x in range(L)] for y in range(W)] 

2
Jawaban rangkap dari satu jawaban di bawah ini. Juga [[0]*(L) for i in range(W)]harus [[0]*(L) for _ in range(W)]karena itidak digunakan di mana pun
Ayush Vatsyayan

2

Anda dapat membuat daftar dua dimensi kosong dengan menyarangkan dua atau lebih bracing persegi atau braket ketiga ( [], dipisahkan dengan koma) dengan bracing persegi, seperti di bawah ini:

Matrix = [[], []]

Sekarang misalkan Anda ingin menambahkan 1 untuk Matrix[0][0]kemudian Anda ketik:

Matrix[0].append(1)

Sekarang, ketik Matrix dan tekan Enter. Outputnya adalah:

[[1], []]

1

Coba ini:

rows = int(input('Enter rows\n'))
my_list = []
for i in range(rows):
    my_list.append(list(map(int, input().split())))

1

Jika Anda membutuhkan matriks dengan angka yang telah ditentukan, Anda dapat menggunakan kode berikut:

def matrix(rows, cols, start=0):
    return [[c + start + r * cols for c in range(cols)] for r in range(rows)]


assert matrix(2, 3, 1) == [[1, 2, 3], [4, 5, 6]]

1

Berikut ini cuplikan kode untuk membuat matriks dalam python:

# get the input rows and cols
rows = int(input("rows : "))
cols = int(input("Cols : "))

# initialize the list
l=[[0]*cols for i in range(rows)]

# fill some random values in it
for i in range(0,rows):
    for j in range(0,cols):
        l[i][j] = i+j

# print the list
for i in range(0,rows):
    print()
    for j in range(0,cols):
        print(l[i][j],end=" ")

Tolong sarankan jika saya melewatkan sesuatu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.