파이썬에서 2 차원 배열을 정의하는 방법


723

초기화 길이가없는 2 차원 배열을 다음과 같이 정의하고 싶습니다.

Matrix = [][]

그러나 그것은 작동하지 않습니다 ...

아래 코드를 시도했지만 잘못되었습니다.

Matrix = [5][5]

오류:

Traceback ...

IndexError: list index out of range

내 실수는 무엇입니까?


14
하나는 배열 또는 다른 것을 정의 하지 않습니다 . 그러나 여기에 표시된 것처럼 다차원 시퀀스를 만들 수 있습니다. 파이썬 변수 는 형식화되지 않았지만 은 강력하게 형식화됩니다.
SingleNegationElimination가

1
혼란 스러워요. 다른 언어에서 유래 : 그것은 1D- 배열을 포함하는 1D- 배열과 2D- 배열의 차이점입니다. 그리고 AFAIK는 파이썬에서 다차원 배열 (또는 목록)을 가질 수있는 방법이 없습니다. 여기에서 말해야합니다 ...
Dirk Reichel

답변:


1008

기술적으로 초기화되지 않은 배열을 색인하려고합니다. 항목을 추가하기 전에 먼저 목록으로 외부 목록을 초기화해야합니다. 파이썬은 이것을 "목록 이해력"이라고 부릅니다.

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

이제 목록에 항목을 추가 할 수 있습니다.

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

매트릭스는 "y"주소 주이며, "y 인덱스"는 "x 인덱스"앞에옵니다.

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

원하는대로 이름을 지정할 수 있지만 내부 및 외부 목록 모두에 "x"를 사용하고 정사각형이 아닌 매트릭스를 원할 경우 인덱싱에 발생할 수있는 혼동을 피하기 위해이 방법을 살펴 봅니다.


219
[[범위에있는 x의 경우 0 (cols_count)] 범위에있는 x의 경우 (rows_count)]
songhir

3
ademar111190에 의해 홀수 편집. Python 3에는 xrange가 없지만 Python 2를 사용해야하는 경우 불필요하게 객체를 만들지 않으려는 경우 xrange가 올바른 함수입니다.
Dave

4
@dave 0으로 채워질 필요가없는 경우 range, 내부 목록을 직접 작성하는 데 사용할 수 있습니다.[range(5) for x in range(5)]
alanjds

2
@alanjds-그건 사실이지만 외부 반복을 위해 파이썬 2에서 잠재적으로 많은 불필요한 객체 참조를 생성합니다 (매우 큰 범위로 시도하십시오). 또한 어떤 값으로 초기화하는 것은 거의 항상 원하는 것입니다. 이것은 0보다 많지 않습니다. range는 반복 가능한 컬렉션을 생성합니다. xrange는 생성기를 반환합니다. 내 요점은 아데 마르가 실제로 그의 수정보다 더 정확하고 효율적인 무언가를 "수정"했다는 것이다.
Dave

10
@ 6packkid [0] * w부분은 좋지만 [[0] * w] * h]예기치 않은 동작이 발생합니다. 시도 mat = [[0] * 3] * 3; mat[0][1] = 10; print(mat == [[0, 10, 0], [0, 10, 0], [0, 10, 0]])mat = [[0] * 3 for i in range(3)]; mat[0][1] = 10; print(mat == [[0, 10, 0], [0, 0, 0], [0, 0, 0]]).
senderle

407

행렬을 정말로 원한다면을 사용하는 것이 좋습니다 numpy. 행렬 연산은 numpy대부분 2 차원 배열 유형을 사용합니다. 새로운 배열을 만드는 방법에는 여러 가지가 있습니다. 가장 유용한 zeros기능 중 하나는 모양 매개 변수를 사용하여 지정된 모양의 배열을 반환하며 값이 0으로 초기화 된 함수입니다.

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

다음은 2 차원 배열과 행렬을 만드는 다른 방법입니다 (압축성을 위해 출력을 제거함).

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

numpy제공하지 않습니다 matrix뿐만 아니라 유형을하지만,이되어 더 이상 권장 에 대한 모든 사용 및 제거 할 수있다 numpy미래입니다.


79
행렬을 원할 때마다 numpy를 사용하려고합니다. 이 답변이 먼저되어야합니다.
Pat B

2
질문에 영어 단어 "행렬"을 사용한다고해서 질문 np.matrix을 나타내는 데 사용해야한다는 의미는 아닙니다 . numpy에서 행렬을 나타내는 올바른 방법은을 사용하는 것 array입니다.
user2357112는 Monica

@ user2357112, 보시다시피 위에 나열된 대부분 의 예제 array는 행렬 대신을 출력 합니다. 항상 권장되는 것은 아니지만 matrix상황에 맞는 합법적 인 이유가 있습니다 .
senderle

1
@senderle, 사용 이유를 확장 할 수 있습니까 matrix? 때문에 @운영자가 도입되었다,이 게시물이 기록 된 이후 한 적은 이유가있을 것 같습니다.
jpp

1
@jpp는 이전에 언급했듯이 matlab에서 온 사람들이 유용하다고 생각할 수 있습니다. 그러나 numpy문서는 이제 클래스가 더 이상 사용되지 않아 제거 될 수 있다고 표시 하므로 답변에서 제외했습니다.
발신자

337

다음은 목록 목록을 초기화하기위한 짧은 표기법입니다.

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

불행히도 이것을 같은 것으로 단축하는 5*[5*[0]]것은 실제로 작동하지 않습니다. 왜냐하면 동일한 목록의 사본 5 개로 끝나기 때문에 그중 하나를 수정하면 모두 변경됩니다. 예를 들면 다음과 같습니다.

>>> 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
"단축"실패의 논리를 설명해 주시겠습니까? 이 경우 파이썬은 왜 같은 목록의 사본을 출력하고 다른 경우에는 다른 셀의 배열을 출력 [0]*5합니까?
mike622867

12
위의 주석은 정확히 사실이 아닙니다. [0] * 5는 여전히 숫자 0을 나타내는 동일한 객체에 대한 참조의 5 배를 갖는 시퀀스를 생성합니다. 또는 기본 데이터 유형으로 생각할 수도 있습니다. 불변이기 때문에 사본 대신 동일한 객체에 대한 참조에 문제가 발생하지 않습니다.)
dreua

4
더 많은 pythonic : [[0]*5 for _ in range(5)]당신이 사용하지 않는 익명의 루프 카운터
Jean-François Fabre

두 번째 예에서 얕은 복사 문제를 지적하게되어 기쁩니다.
whatacold December

@dreua 덕분에, 정말 [0]*5잘 작동 하는 방식 이 혼란 스러웠습니다 . 이제는 왜 [{0}]*8나쁜 생각 인지 이해 합니다.
kuku

110

빈 행렬을 만들려면 올바른 구문은

matrix = [[]]

0으로 채워진 크기 5의 행렬을 생성하려면

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

@KorayTugay 행렬은 다른 목록 (열) 안에 중첩 된 Python 목록 (행)을 사용하여 표시되기 때문입니다.
elig

2
파이썬 -3의 경우 xrange func 대신 range 함수를 사용하십시오
Rakesh Chaudhari

76

원하는 것이 일부 요소를 담는 2 차원 컨테이너라면, 대신 사전을 편리하게 사용할 수 있습니다.

Matrix = {}

그럼 당신은 할 수 있습니다 :

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

이것은 1,2튜플 이기 때문에 작동 하며 사전을 색인화하는 키로 사용하고 있습니다. 결과는 멍청한 희소 행렬과 유사합니다.

osa 및 Josap Valls에 의해 표시된대로 Matrix = collections.defaultdict(lambda:0)누락 된 요소의 기본값이로 설정되도록 사용할 수도 있습니다 0.

Vatsal은이 방법이 아마도 큰 행렬에는 그리 효율적이지 않으며 코드의 성능에 중요하지 않은 부분에만 사용해야한다고 지적합니다.


2
그런 다음 import collections; Matrix = collections.defaultdict(float)초기화되지 않은 요소를 0으로 대체하기 위해을 수행 할 수도 있습니다 .
osa

2
키가 최악의 경우 O (n)의 복잡성을 갖기 때문에 tuple (1,2)에 대한 dict에 액세스하지 않습니다. 내부적으로 튜플을 해시합니다. 2D 배열을 사용하면 인덱스 [1,2] 액세스에 액세스하는 데 O (1) 시간이 복잡해집니다. 따라서 이것을 위해 dict를 사용하는 것은 좋은 선택이 아닙니다.
Vatsal

@Vatsal wiki.python.org/moin/TimeComplexity에 따르면 평균 사례는 O (1)이지만 최악의 경우는 옳습니다. 어쨌든 많은 항목에 대해 이야기하지 않는 한이 차이점에 대해서는 신경 쓰지 않을 것입니다. 사실, 액세스 시간보다 메모리가 더 걱정됩니다.
enobayram

또한 알고리즘의 전체적인 복잡성이 O (n ^ 2) 이상이 될 때까지 항상 dicts를 사용하지 않도록 노력합니다. 'n'곱하기 O (n) 액세스는 O (n ^ 2) 복잡성을 제공합니다.
Vatsal

@enobayram, 죄송하지만 동의하지 않습니다. 최악의 경우 O (n) 액세스가 'n'번 수행되면 점근 분석은 항상 O (n ^ 2)를 제공합니다. 할부 상환 분석은 더 적은 범위를 제공 할 수 있습니다. 그리고 상각과 평균 사례 사이에는 큰 차이가 있습니다 ... 가정과 모호한 의견을
말하기

42

파이썬에서는리스트리스트를 만들 것입니다. 치수를 미리 선언 할 필요는 없지만 가능합니다. 예를 들면 다음과 같습니다.

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

이제 matrix [0] [0] == 2 및 matrix [1] [0] == 3입니다. 목록 이해 구문을 사용할 수도 있습니다. 이 예제에서는 두 번 사용하여 "2 차원 목록"을 작성합니다.

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
extend첫 번째 경우에도 도움이 될 것입니다.로 시작 m = [[]]하면을 사용하여 내부 목록에 추가하고 (행 확장) m[0].extend([1,2])을 사용하여 외부 목록에 추가 (새 행 추가) m.append([3,4])할 수 있습니다 [[1, 2], [3, 4]].
askewchan

22

받아 들인 대답은 좋고 정확하지만 완전히 빈 배열을 만드는 데 사용할 수 있다는 것을 이해하는 데 시간이 걸렸습니다.

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

결과

[[], [], []]

22

목록의 목록을 작성해야하며 가장 좋은 방법은 중첩 된 이해를 사용하는 것입니다.

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

당신에 [5][5]예를 들어, 당신은 정수 "5"내부에있는 목록을 작성, 그것의 5 항목에 액세스하려고, 더 5 항목이 없기 때문에 그것은 자연스럽게 IndexError를 제기하고 있습니다 :

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

실제로 row_index ( 'i') 및 column_index ( 'j')의 순서는 다음과 같습니다. '>>> matrix = [[range (5)의 column_index의 경우 0] 범위 (5)의 row_index에 대한]]'
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)

왜 그렇게 긴 코드가 필요한 Python가요?

오랫동안 파이썬에 익숙하지 않았을 때 2D 행렬 작성에 대한 한 줄 답변을 보았고 파이썬에서 다시 2D 행렬을 사용하지 않을 것이라고 말했습니다. (이 한 줄은 꽤 무서웠으며 파이썬이하고있는 일에 대한 정보를주지 못했습니다. 또한 이러한 속기에 대해 알지 못합니다.)

어쨌든, 여기 C, CPP 및 Java 배경에서 온 초보자를위한 코드가 있습니다.

파이썬 애호가와 전문가에 대한 참고 사항 : 자세한 코드를 작성했기 때문에 투표하지 마십시오.


13

쉽게 읽을 수 있도록 다시 작성 :

# 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

사용하다:

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

첫 번째 차원의 * 5는이 수준에서 데이터를 변경할 수 없기 때문에 작동합니다.


5
아마 이것을 다음과 같이 쓸 것입니다matrix = [[0]*cols for _ in range(rows)]
Shital Shah

12

0의 행렬을 선언하려면 :

numpy.zeros((x, y))

예 :

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

또는 numpy.ones ((x, y)) 예

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

3 차원도 가능합니다. ( http://www.astro.ufl.edu/~warner/prog/python.html 참조-> 다차원 배열)


12

이것은 일반적으로 파이썬에서 2D 배열을 만드는 방법입니다.

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

목록 이해에서 두 개의 for 루프를 사용하는 것과 비교할 때이 구문을 기억하기 쉽다는 것을 알았습니다.


11

나는 첫 번째 파이썬 스크립트를 사용하고 있으며 정사각 행렬 예제에 약간 혼란 스러웠으므로 아래 예제가 시간을 절약하는 데 도움이되기를 바랍니다.

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

그래서

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

10

NumPy를 사용하면 다음과 같이 빈 행렬을 초기화 할 수 있습니다.

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

나중에 다음과 같은 데이터를 추가하십시오.

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

"목록 이해"보다는 numpy를 사용하는 장단점이 무엇입니까?
Monica에 대한 Revolucion

7

쉼표로 구분 된 파일을 다음과 같이 읽습니다.

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

"data"목록은 색인 데이터가있는 목록의 목록입니다 [row] [col]


7

목록 목록 (내 의견으로는 훨씬 자연 스럽습니다)의 관점에서 생각하지 않고 2D 배열로 생각하고 싶다면 다음을 수행 할 수 있습니다.

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

결과는 NumPy 배열이 아닌 목록이며 숫자, 문자열 등으로 개별 위치를 덮어 쓸 수 있습니다.


있습니다 numpy.matrix에 해당 numpy.zeros목록을받지 않고 0이 붙지 않는?
Monica에 대한 Revolucion

6

그것이 사전 을위한 것입니다!

matrix = {}

두 가지 방법으로 을 정의 할 수 있습니다 .

matrix[0,0] = value

또는

matrix = { (0,0)  : value }

결과:

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

6

사용하다:

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

NumPy가 갈 길이라고 생각합니다. 위의 내용은 NumPy를 사용하지 않으려는 경우 일반적인 것입니다.


나는 numpy를 사용하지 않고 바닐라 파이썬으로 간단한 것을 시도하는 것을 좋아합니다.
Rick Henderson

4

list를 사용하여 :

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

dict를 사용하여 : 빠른 검색을 위해 해시 테이블 에이 정보를 저장할 수도 있습니다.

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

행렬 [ '1']은 O (1) 시간의 결과를 제공합니다

* nb : 해시 테이블에서 충돌을 처리해야합니다.


4

시작하기 전에 크기 정보가 없으면 두 개의 1 차원 목록을 작성하십시오.

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

전체 행을 첫 번째 목록에 저장하십시오. 완료되면 목록 1을 목록 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

산출:

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

이 짧은 표현에주의하십시오. @ FJ의 답변에서 자세한 설명을 참조하십시오


19
때문에,이 방법으로주의 Matrix[0], Matrix[1], ..., Matrix[4]같은 배열에 대한 모든 점, 그래서 한 후 Matrix[0][0] = 3, 당신이 기대하는 것입니다 Matrix[0][0] == Matrix[1][0] == ... == Matrix[4][0] == 3.
gongzhitaao

1
귀하의 의견에 대해 gongzhitaao에게 감사드립니다. 내가 그것을 30 분 이상 절약했을 것이라고 생각했다면 .. 각 행이 메모리에서 같은 곳을 가리키는 행렬을 갖는 것은별로 유용하지 않은 것 같습니다. 심지어 위험하다! 나는 이것이 질문을 한 Masoud Abasian 이하 고 싶은 것이 아니라고 확신합니다.
Adrian

7
이 답변은 정답이 아니므로 제거해야합니다. 초보자는 혼란 스러울 수 있습니다.
cxxl

2
어떤 대답을하십니까? 이름이 "FJ"인 사용자가 표시되지 않습니다 (삭제 된 답변이 아님).
피터 Mortensen

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

다음보다 빠릅니다.

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

2
아래에 이미 답변 된 답변이 중복되었습니다. 또한 [[0]*(L) for i in range(W)]해야 [[0]*(L) for _ in range(W)]하기 때문에 i사용 어디서나 아니다
Ayush Vatsyayan

2

다음과 같이 두 개 이상의 정사각형 브레이스 또는 세 번째 괄호 ( []쉼표로 구분)를 쉼표로 구분 하여 빈 2 차원 목록을 만들 수 있습니다 .

Matrix = [[], []]

이제 1을 추가하고 Matrix[0][0]다음을 입력 한다고 가정하십시오 .

Matrix[0].append(1)

이제 Matrix를 입력하고 Enter를 누르십시오. 출력은 다음과 같습니다.

[[1], []]

1

이 시도:

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

1

사전 정의 된 숫자가있는 행렬이 필요한 경우 다음 코드를 사용할 수 있습니다.

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

다음은 파이썬에서 행렬을 만들기위한 코드 스 니펫입니다.

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

내가 놓친 것이 있으면 제안하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.