Python'da iki boyutlu bir dizi nasıl tanımlanır


728

Bu gibi bir başlangıç ​​uzunluğu olmadan iki boyutlu bir dizi tanımlamak istiyorum:

Matrix = [][]

ama bu çalışmıyor...

Aşağıdaki kodu denedim, ama çok yanlış:

Matrix = [5][5]

Hata:

Traceback ...

IndexError: list index out of range

Benim hatam nedir?


14
Kişi dizileri veya başka bir şeyi tanımlamaz . Bununla birlikte, buradaki yanıtların gösterdiği gibi, çok boyutlu diziler oluşturabilirsiniz. Python değişkenlerinin türsüz olduğunu, ancak değerlerin güçlü bir şekilde yazıldığını unutmayın.
SingleNegationElimination

1
Kafam karıştı. Diğer dillerden geliyor: 1D-Dizileri içeren bir 1D-Dizisi ile bir 2D-Dizisi arasındaki farktır. Ve AFAIK, python'da çok boyutlu bir diziye (veya listeye) sahip olmanın bir yolu yoktur. Burada söylenmeli ...
Dirk Reichel

Yanıtlar:


1014

Teknik olarak başlatılmamış bir dizini dizine eklemeye çalışıyorsunuz. Öğe eklemeden önce dış listeyi listelerle başlatmanız gerekir; Python buna "liste kavraması" adını verir.

# 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)] 

Artık listeye öğe ekleyebilirsiniz:

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

Matrisin "y" adres majör olduğunu, başka bir deyişle "y indeksinin" x indeksinden önce geldiğini unutmayın.

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

Bunları istediğiniz gibi adlandırabilseniz de, hem iç hem de dış listeler için "x" kullanırsanız ve kare olmayan bir Matris istiyorsanız, indekslemeyle ortaya çıkabilecek bazı karışıklıkları önlemek için bu şekilde bakarım.


219
[[Aralıktaki x için (cols_count)]] aralıktaki x için (rows_count)]
songhir

3
Ademar111190 tarafından tek düzenleme. Python 3'te xrange yoktur, ancak Python 2'yi kullanmanız gerekiyorsa, xrange gereksiz yere nesne oluşturmak istemiyorsanız kullanmak için doğru işlevdir.
Dave

4
@ dave Sıfır doldurulmuşa ihtiyacınız yoksa range, doğrudan dahili listeleri oluşturmak için kullanabilirsiniz :[range(5) for x in range(5)]
alanjds

2
@alanjds - bu doğru, ancak yine de dış yineleme için Python 2'de potansiyel olarak gereksiz birçok nesne başvurusu oluşturuyorsunuz (bunu ÇOK geniş bir aralıkta deneyin). Ayrıca, bir değere başlatma neredeyse her zaman istediğiniz şeydir - ve bu 0'dan daha sık değildir. Aralık yinelenebilir bir koleksiyon verir - xrange bir jeneratör döndürür. Demek istediğim, ademar'ın aslında düzeltmesinden daha doğru ve verimli olan bir şeyi "düzeltti".
Dave

10
@ 6packkid [0] * wparçası güzel, ama [[0] * w] * h]beklenmedik davranış üretecek. Deneyin mat = [[0] * 3] * 3; mat[0][1] = 10; print(mat == [[0, 10, 0], [0, 10, 0], [0, 10, 0]])ve mat = [[0] * 3 for i in range(3)]; mat[0][1] = 10; print(mat == [[0, 10, 0], [0, 0, 0], [0, 0, 0]]).
senderle

409

Gerçekten bir matris istiyorsanız, kullanmaktan daha iyi olabilirsiniz numpy. Matris işlemleri numpyçoğunlukla iki boyutlu bir dizi türü kullanır. Yeni bir dizi oluşturmanın birçok yolu vardır; en kullanışlı olanlardan biri, zerosşekil parametresini alan ve verilen şeklin bir dizisini döndüren ve değerlerin sıfır olarak başlatılması işlevidir:

>>> 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.]])

Aşağıda, 2 boyutlu diziler ve matrisler oluşturmanın başka yolları da vardır (kompaktlık için çıktı kaldırılmış olarak):

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

numpybir matrixtür sağlar , ancak artık herhangi bir kullanım için önerilmeznumpy ve gelecekte kaldırılabilir .


80
Matris istediğinizde numpy kullanmak istiyorsunuz. Bu cevap ilk önce olmalı.
Pat B

3
Sorunun İngilizce "matris" kelimesini kullanması np.matrix, onu temsil etmek için kullanmaları gerektiği anlamına gelmez . Bir matrisi numpy cinsinden göstermenin uygun yolu bir array.
user2357112 Monica

@ user2357112, Ve gördüğünüz gibi, yukarıda listelenen örneklerin çoğuarray matris yerine çıktılar . Her zaman teşvik edilmese de, kullanım için meşru nedenler vardır matrix- bağlam konuları.
senderle

1
@senderle, Kullanım nedenlerini genişletebilir misiniz matrix? Yana @operatör tanıtıldı, bu yazı yazılmıştır beri bir eksik sebebi var gibi görünüyor.
jpp

1
@jpp, daha önce yazdığı gibi, matlab'dan gelen insanlar bunu faydalı bulabilir. Ancak numpydokümanlar artık sınıfın kullanımdan kaldırılabileceğini ve gelecekte kaldırılabileceğini gösteriyor , bu yüzden onu cevabın dışına çıkardım.
senderle

337

Listelerin bir listesini başlatmak için daha kısa bir gösterim:

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

Maalesef bunu aynı şekilde kısaltmak 5*[5*[0]]gerçekten işe yaramaz çünkü aynı listenin 5 kopyasını elde edersiniz, bu nedenle bunlardan birini değiştirdiğinizde hepsi değişir, örneğin:

>>> 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
"Kısalma" başarısızlığının arkasındaki mantığı açıklayabilir misiniz? Python neden bu listede aynı listenin kopyalarını ve durumunda farklı hücreler dizisi çıkarıyor [0]*5?
mike622867

12
Yukarıdaki yorumlar tam olarak doğru değildir: [0] * 5 hala 0 sayısını temsil eden aynı Object'e 5 kez referansla bir dizi oluşturur. Ancak 0 farkedilemez çünkü 0 değişmez. - ya da onu ilkel bir veri türü olarak düşünebilirsiniz - çünkü değişmezdir, bu yüzden kopya yapmak yerine aynı nesneye yapılan referanslarla ilgili sorun
yaşamazsınız

4
daha pythonic: [[0]*5 for _ in range(5)]anonim döngü sayacı ile kullanmıyorsunuz
Jean-François Fabre

İkinci örnekte sığ kopya sorununa dikkat çekiyorsunuz.
whatacold

teşekkürler @ dreua, gerçekten nasıl iyi [0]*5çalışıyor kafam karıştı . Şimdi neden [{0}]*8kötü bir fikir olacağını anlıyorum .
kuku

110

Boş bir matris oluşturmak istiyorsanız, doğru sözdizimi

matrix = [[]]

Ve 0 ile dolu 5 büyüklüğünde bir matris oluşturmak istiyorsanız,

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

@KorayTugay Matris, başka bir listenin (sütunlar) içine yerleştirilmiş Python listeleri (satırları) kullanılarak temsil edildiğinden.
elig

2
Python-3 için xrange fonk yerine aralık fonksiyonunu kullanın
Rakesh Chaudhari

77

İstediğiniz tek şey bazı öğeleri tutmak için iki boyutlu bir kapsa, bunun yerine uygun bir sözlük kullanabilirsiniz:

Matrix = {}

Sonra şunları yapabilirsiniz:

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

Bu 1,2bir demet olduğu için çalışır ve sözlüğü dizine eklemek için bir anahtar olarak kullanırsınız. Sonuç, aptal seyrek bir matrise benzer.

Osa ve Josap Valls tarafından belirtildiği gibi Matrix = collections.defaultdict(lambda:0), eksik öğelerin varsayılan değeri olan bir değer de kullanabilirsiniz 0.

Vatsal ayrıca, bu yöntemin büyük matrisler için muhtemelen çok verimli olmadığını ve yalnızca kodun performans açısından kritik olmayan kısımlarında kullanılması gerektiğini belirtmektedir.


2
Daha sonra import collections; Matrix = collections.defaultdict(float), başlatılmamış öğelerin yerine sıfırlar da yapabilirsiniz .
osa

2
Tuple (1,2) için bir diksiyona erişmenin anahtar olarak O (n) en kötü durum karmaşıklığına sahip olması. Dahili olarak tuples hash olurdu. 2B bir dizi kullanmak, dizin [1,2] erişimine O (1) zaman karmaşıklığı verecektir. Yani bunun için dikt kullanmak iyi bir seçim olmamalı.
Vatsal

@Vatsal wiki.python.org/moin/TimeComplexity , ortalama davanın O (1) olduğunu söylüyor, ancak en kötü durumda haklısınız. Her neyse, bir sürü öğe hakkında konuşmazsanız bu farkı umursamazsınız. Aslına bakılırsa, erişim zamanından çok bellek konusunda endişelenirim.
enobayram

Ayrıca algoritmanın genel karmaşıklığı O (n ^ 2) değerine eşit veya daha büyük olana kadar diktatların kullanılmasından daima kaçınırız. Bir 'n' kez O (n) erişim O (n ^ 2) karmaşıklığı verecektir.
Vatsal

@enobayram, Üzgünüm ama aynı fikirde değilim. En kötü durum O (n) erişimi 'n' kez yapılırsa, asimptotik analiz her zaman O (n ^ 2) verecektir. Amortisman analizi daha az sınır verebilir. İtfa edilmiş ve ortalama dava arasında büyük bir fark var ... lütfen herhangi bir varsayım ve belirsiz yorum yapmadan önce bakın
Vatsal

42

Python'da bir liste listesi oluşturacaksınız. Boyutları önceden bildirmek zorunda değilsiniz, ancak yapabilirsiniz. Örneğin:

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

Şimdi matris [0] [0] == 2 ve matris [1] [0] == 3. Liste anlama sözdizimini de kullanabilirsiniz. Bu örnek, iki boyutlu bir "iki boyutlu liste" oluşturmak için kullanır:

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
extendilk durumda da yardımcı olur: ile başlarsanız m = [[]], o zaman iç listeye (bir satırı genişlet) m[0].extend([1,2])ekleyebilir ve dış listeye (yeni bir satır ekle ) ekleyebilir m.append([3,4]), bu işlemler sizi bırakacaktır [[1, 2], [3, 4]].
askewchan

22

Kabul edilen cevap iyi ve doğru, ama tamamen boş bir dizi oluşturmak için de kullanabileceğimi anlamak biraz zaman aldı.

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

sonuç

[[], [], []]

22

Listelerin bir listesini yapmalısınız ve en iyi yol iç içe kavrayışları kullanmaktır:

>>> 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]]

Senin üzerinde [5][5]örneğin, bir tamsayı "5" içeride olan bir listesini oluşturarak, ve 5 öğeye erişmek için denemek ve hiçbir 5 öğe olduğundan bu doğal bir IndexError yükseltir gibidir:

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

Aslında row_index ('i') ve column_index ('j') için sıralama şu şekildedir: '>>> matris = [[aralıktaki (5) sütun_index için 0]] (5) aralığında satır_dizin için]'
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)

Neden bu kadar uzun bir kod, Pythonsizde de soruyorsunuz?

Python ile rahat olmadığımda, 2D matris yazmak için tek satırlık cevapları gördüm ve kendime tekrar Python'da 2-D matris kullanmayacağımı söyledim. (Bu tek satırlar oldukça korkutucuydu ve bana Python'un ne yaptığına dair herhangi bir bilgi vermedi. Ayrıca bu kısayolların farkında olmadığımı da unutmayın.)

Her neyse, C, CPP ve Java arka planından gelen yeni başlayanlar için kod

Python Lovers ve Experts'e not: Sadece ayrıntılı bir kod yazdığım için lütfen oy vermeyin.


14

kullanın:

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

İlk boyut için * 5 işe yarıyor çünkü bu seviyede veriler değişmez.


5
Muhtemelen bunu şöyle matrix = [[0]*cols for _ in range(rows)]
yazardım

13

Kolay okuma için yeniden yazma:

# 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

Python'da genellikle 2D diziler oluşturuyorum.

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

Bu sözdizimini bir liste kavrayışında döngüler için iki kullanmaya kıyasla hatırlaması kolay buluyorum.


12

Sıfırlardan oluşan bir matris bildirmek için:

numpy.zeros((x, y))

Örneğin

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

veya numpy.ones ((x, y)) ör.

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

Üç boyut bile mümkündür. ( http://www.astro.ufl.edu/~warner/prog/python.html bkz. -> Çok boyutlu diziler)


11

İlk Python betiğimin üzerindeyim ve kare matris örneği ile biraz kafam karıştı, bu yüzden aşağıdaki örneğin biraz zaman kazanmanıza yardımcı olacağını umuyorum:

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

Böylece

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

10

NumPy'yi kullanarak boş matrisi şu şekilde başlatabilirsiniz:

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

Ve daha sonra bunun gibi veriler ekleyin:

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

"liste kavraması" yerine numpy kullanmanın avantaj ve dezavantajları ne olabilir?
Monica

7

Virgülle ayrılmış dosyalarda şöyle okudum:

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

"Veri" listesi, dizin verileri [satır] [col] içeren listelerin listesidir.


7

Ne en That Sözlük için yapılır!

matrix = {}

Anahtarları ve değerleri iki şekilde tanımlayabilirsiniz :

matrix[0,0] = value

veya

matrix = { (0,0)  : value }

Sonuç:

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

7

Liste listesi açısından düşünmeye zorlanmak yerine bunu 2D bir dizi olarak düşünmek istiyorsanız (bence çok daha doğal), aşağıdakileri yapabilirsiniz:

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

Sonuç bir listedir (NumPy dizisi değil) ve sayı, dize, her neyse ayrı ayrı konumların üzerine yazabilirsiniz.


Hangi numpy.matrixeşdeğer numpy.zerosliste olmadan sıfır olmadan?
Monica

6

kullanın:

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

Ben NumPy gitmek için bir yol olduğunu düşünüyorum. NumPy'yi kullanmak istemiyorsanız yukarıdaki genel bir işlemdir.


Vanilya Python ile numpy kullanmak zorunda kalmadan basit bir şey yapma girişimini seviyorum.
Rick Henderson

4

listeyi kullanarak:

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

dict kullanarak: bu bilgileri hızlı arama için karma tabloda da saklayabilirsiniz.

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]};

matris ['1'] size O (1) süresi ile sonuç verecektir

* nb : karma tablosundaki bir çarpışma ile başa çıkmanız gerekiyor


4

Başlamadan önce boyut bilginiz yoksa, iki adet tek boyutlu liste oluşturun.

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

Satırın tamamını 1. listede saklayın. Tamamlandığında, liste 1'i liste 2'ye ekleyin:

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

Çıktı:

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

Bu kısa ifadeye dikkat edin, @ FJ'nin cevabında tam açıklamaya bakın


19
Bu şekilde dikkatli olun, çünkü Matrix[0], Matrix[1], ..., Matrix[4]hepsi aynı diziyi gösterir, bu yüzden sonra Matrix[0][0] = 3beklersiniz Matrix[0][0] == Matrix[1][0] == ... == Matrix[4][0] == 3.
gongzhitaao

1
Yorumunuz için teşekkürler gongzhitaao. Daha iyi okumuş olsaydım en az yarım saatimi kurtarırdı .. Her satırın bellekte aynı yere işaret ettiği bir matrise sahip olmak çok faydalı görünmüyor ve ne yaptığınızın farkında değilseniz tehlikeli bile! Soruyu soran Mesut Abasyan'ın yapmak istediği bu olmadığından eminim.
Adrian

7
Doğru cevabı olmadığı için bu cevabı kaldırmalısınız. Yeni başlayanlar şaşkın olabilir.
cxxl

2
Hangi cevaba atıfta bulunuyorsunuz? "FJ" adında bir kullanıcı göremiyorum (silinen cevaplarda bile).
Peter Mortensen

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

Şundan daha hızlı olacak:

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

2
Aşağıda zaten cevaplanmış olanlardan birinin yinelenen cevabı. Ayrıca [[0]*(L) for i in range(W)]olmalıdır [[0]*(L) for _ in range(W)]çünkü ikullanılan yerde değil
Ayush Vatsyayan

2

İki veya daha fazla köşeli parantez veya üçüncü köşeli parantezleri ( []virgülle ayrılmış olarak) tıpkı aşağıdaki gibi köşeli parantez içine yerleştirerek boş iki boyutlu bir liste oluşturabilirsiniz :

Matrix = [[], []]

Şimdi şunu Matrix[0][0]yazın 1 eklemek istediğinizi varsayalım :

Matrix[0].append(1)

Şimdi Matrix yazın ve Enter tuşuna basın. Çıktı şöyle olacaktır:

[[1], []]

1

Bunu dene:

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

1

Önceden tanımlanmış sayılara sahip bir matrise ihtiyacınız varsa, aşağıdaki kodu kullanabilirsiniz:

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

Python'da bir matris oluşturmak için kod snippet'i:

# 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=" ")

Bir şey kaçırırsam lütfen önerin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.