파이썬 요소 컬렉션을 저장하고 조작할 수 있는 목록이라는 강력한 데이터 구조를 제공합니다. 또한 2차원 목록/배열을 만드는 다양한 방법을 제공합니다. 그러나 이러한 방법은 코드에서 추적하기 매우 어려운 문제를 일으킬 수 있으므로 이러한 방법의 차이점을 알아야 합니다. 이 기사에서는 Python에서 2D 배열/목록을 사용하는 올바른 방법을 살펴보겠습니다.
2D 배열/목록을 올바른 방법으로 사용하기
2D 배열/목록을 올바른 방법으로 사용하려면 구조를 이해하고, 요소에 액세스하고, 2차원 그리드에서 데이터를 효율적으로 조작해야 합니다. 구조화된 데이터나 그리드로 작업할 때 2D 배열이나 목록이 유용할 수 있습니다. 2D 배열은 본질적으로 목록의 목록으로, 행과 열로 구성된 테이블과 같은 구조를 나타냅니다.
1차원 목록 만들기
Python에서 선형 시퀀스로 요소 컬렉션을 초기화하려면 기본 프로세스인 1D 배열을 만들어야 합니다. Python에는 '1D 배열'이라는 내장 데이터 구조가 없지만 동일한 기능을 달성할 수 있는 목록을 사용할 수 있습니다. Python 목록은 동적이며 다재다능하므로 1D 배열을 나타내는 데 탁월한 선택입니다. 0으로 초기화된 N 크기의 1차원 배열을 생성하는 일반적인 방법부터 살펴보겠습니다.
Naive 방법을 사용하여 1D 목록 만들기
Python의 고급 기능이나 구문을 사용하지 않고 수동으로 목록을 초기화하고 채우는 것은 Naive Methods를 사용하여 1D 목록을 만드는 것으로 알려져 있습니다.
파이썬3
N>=> 5> ar>=> [>0>]>*>N> print>(ar)> |
>
>
산출
[0, 0, 0, 0, 0]>
List Comprehension을 사용하여 1D 목록 만들기
여기서는 행 수에 빈 목록을 곱하므로 전체 목록은 모든 요소가 0인 상태로 생성됩니다.
파이썬3
N>=> 5> arr>=> [>0> for> i>in> range>(N)]> print>(arr)> |
>
>
산출
[0, 0, 0, 0, 0]>
2차원 목록 만들기
2D 배열/목록을 올바른 방법으로 사용하려면 구조를 이해하고, 요소에 액세스하고, 2차원 그리드에서 데이터를 효율적으로 조작해야 합니다. 2D 배열의 사용법을 익히면 복잡한 데이터를 처리하고 다양한 작업을 효율적으로 수행하는 능력을 크게 향상시킬 수 있습니다.
다음을 사용하여 2D 목록 만들기 순진한 방법
여기서는 열 수를 곱하므로 열 수와 동일한 크기의 1차원 목록을 얻은 다음 여기에 행 수를 곱하여 2차원 목록이 생성됩니다.
파이썬3
rows, cols>=> (>5>,>5>)> arr>=> [[>0>]>*>cols]>*>rows> print>(arr)> |
>
>
산출
[[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]]>
메모: 이 방법을 사용하면 때때로 예상치 못한 동작이 발생할 수 있습니다. 이 방법에서는 각 행이 동일한 열을 참조합니다. 즉, 배열의 한 요소만 업데이트하더라도 배열의 동일한 열이 업데이트된다는 의미입니다.
파이썬
rows, cols>=> (>5>,>5>)> arr>=> [[>0>]>*>cols]>*>rows> print>(arr,>'before'>)> arr[>0>][>0>]>=> 1> # update only one element> print>(arr,>'after'>)> |
>
김프 변경 색상
>
산출
([[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]], 'before') ([[1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0], [1, 0, 0, 0, 0]], 'after')>
다음을 사용하여 1D 목록 만들기 목록 이해
여기서 우리는 기본적으로 목록 이해의 개념을 사용하고 목록 내부의 목록에 루프를 적용하여 2차원 목록을 생성합니다.
파이썬3
rows, cols>=> (>5>,>5>)> arr>=> [[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)]> print>(arr)> |
>
>
정렬 배열 자바
산출
[[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]]>
다음을 사용하여 1D 목록 만들기 빈 목록
여기서는 여러 열에 대한 요소로 0을 추가한 다음 이 1차원 목록을 빈 행 목록에 추가하여 2차원 목록을 생성합니다.
파이썬3
arr>=>[]> rows, cols>=>5>,>5> for> i>in> range>(rows):> >col>=> []> >for> j>in> range>(cols):> >col.append(>0>)> >arr.append(col)> print>(arr)> |
>
>
산출
[[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]]>
2D 배열 초기화
제공된 코드는 2D 배열을 초기화하는 두 가지 다른 접근 방식을 보여줍니다. 파이썬 . 첫째, 배열arr>2D 목록 이해를 사용하여 초기화되며, 여기서 각 행은 다음과 같이 생성됩니다.[0, 0, 0, 0, 0]>. 전체 배열은 동일한 내부 목록에 대한 참조 목록으로 생성되어 앨리어싱이 발생합니다. 한 행의 요소에 대한 변경 사항은 모든 행에 반영됩니다. 그런 다음 코드는 중첩된 목록 이해를 사용하여 2D 배열을 생성하는 또 다른 접근 방식을 보여줍니다.arr>. 이 방법은 각 행에 대해 새 목록을 생성하여 앨리어싱을 방지하여 적절한 2D 배열을 생성합니다.
파이썬3
# Python 3 program to demonstrate working> # of method 1 and method 2.> rows, cols>=> (>5>,>5>)> # method 2 1st approach> arr>=> [[>0>]>*>cols]>*>rows> # lets change the first element of the> # first row to 1 and print the array> arr[>0>][>0>]>=> 1> for> row>in> arr:> >print>(row)> # method 2 2nd approach> arr>=> [[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)]> # again in this new array lets change> # the first element of the first row> # to 1 and print the array> arr[>0>][>0>]>=> 1> for> row>in> arr:> >print>(row)> |
>
>
산출
[1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [1, 0, 0, 0, 0] [0, 0, 0, 0, 0] [0, 0, 0, 0, 0] [0, 0, 0, 0, 0] [0, 0, 0, 0, 0]>
설명:
첫 번째 행의 첫 번째 요소만 1로 변경될 것으로 예상하지만 방법 2a에서는 모든 행의 첫 번째 요소가 1로 변경됩니다. 이 독특한 기능은 Python이 우리가 이해하려고 노력할 얕은 목록을 사용하기 때문입니다.
방법 1a에서 Python은 5개의 정수 객체를 생성하지 않고 단 하나의 정수 객체만 생성하며 배열 arr의 모든 인덱스는 표시된 것처럼 동일한 int 객체를 가리킵니다.

0번째 인덱스를 다른 정수(예: 1)에 할당하면 값 1을 사용하여 새로운 정수 객체가 생성되고 0번째 인덱스는 이제 아래와 같이 이 새로운 int 객체를 가리킵니다.

마찬가지로 arr = [[0]*cols]*rows로 2차원 배열을 생성할 때 본질적으로 위의 비유를 확장합니다.
- 정수 객체는 하나만 생성됩니다.
- 단일 1d 목록이 생성되고 해당 목록의 모든 인덱스는 지점 1의 동일한 int 개체를 가리킵니다.
- 이제 arr[0], arr[1], arr[2]… arr[n-1]은 모두 위의 포인트 2에서 동일한 목록 개체를 가리킵니다.
위의 설정은 아래 이미지에서 시각화할 수 있습니다.

이제 arr의 첫 번째 행에 있는 첫 번째 요소를 arr[0][0] = 1로 변경해 보겠습니다.
- arr[0]은 위에서 만든 단일 목록 개체를 가리킵니다. (arr[1], arr[2] …arr[n-1]도 모두 동일한 목록 개체를 가리킨다는 점을 기억하세요).
- arr[0][0]을 할당하면 값이 1인 새 int 개체가 생성되고 arr[0][0]은 이제 이 새 int 개체를 가리킵니다. (그리고 arr[1][0], arr도 마찬가지입니다. [2][0] … arr[n-1][0])
이는 아래 이미지에서 명확하게 볼 수 있습니다.

따라서 2D 배열이 이와 같이 생성되면 기본적으로 하나의 정수 개체만 있고 배열의 모든 행에서 참조되는 목록 개체는 하나만 있기 때문에 특정 행의 값을 변경하면 모든 행에 영향을 미칩니다.
예상한 대로 얕은 목록의 사용으로 인해 발생하는 오류를 추적하는 것은 어렵습니다. 따라서 2D 배열을 선언하는 더 좋은 방법은 다음과 같습니다.
파이썬3
rows, cols>=> (>5>,>5>)> print>([[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)])> |
>
>
산출
[[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]]>
이 방법은 방법 2a와 달리 5개의 별도 목록 개체를 만듭니다. 이를 확인하는 한 가지 방법은 두 피연산자가 동일한 개체를 참조하는지 확인하는 'is' 연산자를 사용하는 것입니다.
파이썬3
rows, cols>=> (>5>,>5>)> # method 2 2nd approach> arr>=> [[>0> for> i>in> range>(cols)]>for> j>in> range>(rows)]> # check if arr[0] and arr[1] refer to> # the same object> print>(arr[>0>]>is> arr[>1>])># prints False> # method 2 1st approach> arr>=> [[>0>]>*>cols]>*>rows> # check if arr[0] and arr[1] refer to the same object prints True because there is only one> #list object being created.> print>(arr[>0>]>is> arr[>1>])> |
>
>
산출
False True>