Unit 23. 2차원 리스트 사용하기
2차원 리스트는 평면 구조 이다. 다음과 같이 가로x세로 형태로 이루어져 있으며, 행(row)과 열(column) 모두 0부터 시작한다.
23.1 2차원 리스트를 만들고 요소에 접근하기
2차원 리스트는 리스트 안에 리스트를 넣어서 만들 수 있다. 안쪽의 각 리스트는 콤마로 구분한다.
- 리스트 = [[값, 값], [값, 값], [값, 값]]
리스트는 가로와 세로를 쉽게 알아내기 위해 다음과 같이 여러 줄로 입력해도 된다.
23.1.1 2차원 리스트의 요소에 접근하기
2차원 리스트의 요소에 접근하거나 값을 할당할 때는 리스트 뒤에 대괄호[ ]를 두 번 사용하며 각각 세로 인덱스와 가로 인덱스를 지정한다.
- 리스트[세로인덱스][가로인덱스]
2차원 리스트도 0부터 시작하기 때문에 가로 첫번째, 세로 첫번째 요소의 인덱스는 [0][0]이다.
톱니형 리스트
다음 리스트 처럼 가로 크기가 불규칙한 리스트를 톱니형 리스트 라고 한다.
톱니형 리스트는 다음과 같이 append메서드를 이용해서도 생성할 수 있다.
2차원 튜플
다음과 같이 튜플안에 튜플을 넣는 방식, 튜플안에 리스트를 넣는 방식, 리스트안에 튜플을 넣는 방식이 있다.
a = ((1,2), (3,4), (5,6))
b = ([1,2], [3,4], [5,6])
c = [(1,2), (3,4), (5,6)]
튜플은 값을 변경할 수 없다는 특징이 있다. 따라서 a는 안쪽과 바깥쪽 요소 모두 변경할 수 없고, b는 안쪽 리스트만 요소를 변경할 수 있고, c는 바깥쪽 리스트만 요소를 변경할 수 있다.
사람이 알아보기 쉽게 출력하기
pprint 모듈의 pprint 함수를 함수를 사용하면 사각형 구조를 유지하도록 출력할 수 있다.
23.2 반복문으로 2차원 리스트의 요소 모두 출력하기
23.2.1 for 반복문을 한 번만 사용하기
for 반복문을 한 번만 사용하는 방법은 다음과 같다.
in 앞의 변수 개수는 2차원 리스트의 가로 크기와 일치해야 한다. for문에서 2차원 리스트가 가로 한 줄 씩 반복되어 안 쪽 리스트에서 요소들을 통째로 꺼내와서 반복문의 변수에 순서대로 대입한다.
23.2.2 for 반복문을 두 번 사용하기
2중 for문으로 2차원 리스트를 출력하는 방법은 다음과 같다.
a = [[1,2], [3,4], [5,6]]
for i in a:
for j in i:
print(j, end=' ')
print()
for i in a: 는 전체 리스트에서 가로를 한 줄씩 꺼내온다. 이후, for j in i에서 안쪽 리스트의 요소를 하나씩 꺼내온다.
23.2.3 for와 range 사용하기
다음과 같이 range에 세로 크기와 가로 크기를 지정해서 리스트의 요소를 인덱스로 접근할 수 있다.
a = [[1,2], [3,4], [5,6]]
for i in range(len(a)):
for j in range(len(a[i])):
print(a[i][j], end=' ')
print()
len(a)로 2차원 리스트의 크기를 구하면 세로 크기(안쪽 리스트의 개수)를 구할 수 있고, len(a[i])로 안쪽 리스트 각각의 안에 있는 요소의 개수를 구할 수 있다. 따라서 a[i][j]로 리스트의 모든 요소들을 출력할 수 있다.
23.2.4 while 반복문을 한 번 사용하기
다음은 while문을 사용하여 2차원 리스트의 요소를 출력한 예시이다.
a = [[1,2], [3,4], [5,6]]
i = 0
while i < len(a):
x, y = a[i]
print(x,y)
i += 1
len(a)로 2차원 리스트의 크기를 구하면 이는 안쪽 리스트의 개수(세로 크기)와 같다. 인덱스를 지정하여 값을 꺼내 올 때는 안쪽 리스트의 요소 개수 만큼 변수를 지정하면 안쪽 리스트(가로)의 요소들을 한 번에 가져올 수 있다.
23.2.5 while 반복문을 두 번 사용하기
다음과 같이 while 반복문을 두 번 사용할 수 도 있다.
a = [[1,2], [3,4], [5,6]]
i = 0
while i < len(a):
j = 0
while j < len(a[i]):
print(a[i][j], end=' ')
j += 1
print()
i += 1
2차원 리스트를 접근할 때는 리스트[세로인덱스][가로인덱스]의 형식으로 접근하기 때문에 while i < len(a): 로 세로 크기만큼 반복하고, while j in len(a[i]): 로 가로 크기 만큼 반복한다. while문으로 요소들을 가져왔기 때문에 각 인덱스는 +1 증가 시켜야 한다.
23.3 반복문으로 리스트 만들기
23.3.1 for 반복문으로 1차원 만들기
다음과 같이 for 반복문으로 반복하면서 append()로 요소를 추가하면 1차원 리스트를 만들 수 있다.
a = []
for i in range(10):
a.append(0)
print(a)
23.3.2 for 반복문으로 2차원 리스트 만들기
for 반복문을 사용하여 2차원 리스트를 만드는 방법은 다음과 같다.
a = []
for i in range(3):
line = []
for j in range(2):
line.append(0)
a.append(line)
print(a)
세로의 크기만큼 반복하며 안쪽 리스트로 사용할 빈 리스트를 만들어야한다. 그리고 가로의 크기만큼 반복하면서 안쪽 리스트에 요소를 추가하면 된다. 리스트에 요소를 추가하는 것은 append()로 추가할 수 있다.
23.3.3 리스트 표현식으로 2차원 리스트 만들기
다음과 같이 리스트 표현식을 사용해서도 2차원 배열을 만들 수 있다.
[0 for j in range(2)] 로 [0,0] 을 만들고 이것을 3번 반복하여 위와 같은 배열을 만든다.
다음과 같이 식 부분에서 [0]리스트 자체를 곱해주면 for 반복문을 한 번만 사용할 수 있다.
23.3.4 톱니형 리스트 만들기
다음과 같이 가로의 크기를 알고 있다고 가정한 상태에서 톱니형 리스트를 만들 수 있다.
a = [3,1,5,2]
b = []
for i in a:
line = []
for j in range(i):
line.append(0)
b.append(line)
print(b)
가로 크기를 저장한 리스트 a를 for문으로 반복하여 가로 크기를 꺼내서 각 가로 크기만큼 0을 빈 리스트에 넣고, 이 리스트를 다시 b에 넣는다. 이것도 다음과 같이 리스트 표현식을 이용해 간단하게 만들 수 있다.
가로 크기가 들어있는 리스트 [3,1,2,3,5]에서 꺼낸 숫자만큼 [0]을 곱해서 톱니형 리스트를 만들 수 있다.
sorted로 2차원 리스트 정렬하기
sorted(반복가능한객체, key=정렬함수, reverse=True 또는 False)의 형식으로 정렬 할 수 있다.
key에 정렬 함수를 지정하여 안쪽 리스트의 요소를 기준으로 정렬했다. student[1]은 안쪽 리스트의 1번 인덱스를 의미하며, student[2]는 안쪽 리스트의 2번 인덱스를 의미한다. 정렬 함수는 람다 표현식을 이용했다.
23.4 2차원 리스트의 할당과 복사
2차원 리스트를 리스트를 다른 변수에 저장해도 같은 객체이기 때문에 요소를 변경하면 두 리스트에 모두 반영된다.
2차원 리스트는 copy를 사용해 복사해도 한 리스트의 요소를 변경하면 두 리스트에 모두 적용된다.
2차원 리스트 이상의 다차원 리스트는 완전히 복사하려면 copy메서드 대신 copy모듈의 deepcopy함수를 사용해야 한다.
copy.deepcopy()는 중첩된 리스트(튜플)에 들어있는 모든 리스트(튜플)을 복사하는 깊은 복사를 해준다.
23.5 퀴즈
정답은 b이다.
정답은 d이다.
정답은 d이다.
정답은 b이다.
정답은 a,c이다.
23.6 연습문제: 3차원 리스트 만들기
정답은 다음 코드와 같다.
[[[for col in range(3)] for row in range(4)] for depth in range (2)]
3차원 리스트는 다음과 같이 높이x가로x세로 의 형태로 되어 있다.
리스트[높이인덱스][세로인덱스][가로인덱스]
23.7 심사문제: 지뢰찾기
정답은 다음 코드와 같다.
col, row = map(int, input().split())
matrix = []
cnt = 0
for i in range(row):
matrix.append(list(input()))
for i in range(len(matrix)):
for j in range(len(matrix[i])):
cnt = 0
if(matrix[i][j] == '.'):
if i == 0 and j == 0:
if matrix[i+1][j] == '*':
cnt += 1
if matrix[i][j+1] == '*':
cnt += 1
if matrix[i+1][j+1] == '*':
cnt += 1
elif i == 0 and j == col-1:
if matrix[i][j-1] == '*':
cnt += 1
if matrix[i+1][j] == '*':
cnt += 1
if matrix[i+1][j-1] == '*':
cnt += 1
elif i == row-1 and j == 0:
if matrix[i][j+1] == '*':
cnt += 1
if matrix[i-1][j] == '*':
cnt += 1
if matrix[i-1][j+1] == '*':
cnt += 1
elif i == row-1 and j == col-1:
if matrix[i-1][j] == '*':
cnt += 1
if matrix[i][j-1] == '*':
cnt += 1
if matrix[i-1][j-1] == '*':
cnt += 1
elif i == 0 and 0 < j < col-1:
if matrix[i+1][j] == '*':
cnt += 1
if matrix[i][j+1] == '*':
cnt += 1
if matrix[i][j-1] == '*':
cnt += 1
if matrix[i+1][j-1] == '*':
cnt += 1
if matrix[i+1][j+1] == '*':
cnt += 1
elif 0 < i < row-1 and j == 0:
if matrix[i+1][j] == '*':
cnt += 1
if matrix[i-1][j] == '*':
cnt += 1
if matrix[i][j+1] == '*':
cnt += 1
if matrix[i-1][j+1] == '*':
cnt += 1
if matrix[i+1][j+1] == '*':
cnt += 1
elif 0 < i < row-1 and 0 < j < col-1: ### 여기 조건까지
if matrix[i+1][j] == '*':
cnt += 1
if matrix[i][j-1] == '*':
cnt += 1
if matrix[i-1][j] == '*':
cnt += 1
if matrix[i][j+1] == '*':
cnt += 1
if matrix[i-1][j-1] == '*':
cnt += 1
if matrix[i-1][j+1] == '*':
cnt += 1
if matrix[i+1][j+1] == '*':
cnt += 1
if matrix[i+1][j-1] == '*':
cnt += 1
elif 0 < i < row-1 and j == col-1:
if matrix[i+1][j] == '*':
cnt += 1
if matrix[i][j-1] == '*':
cnt += 1
if matrix[i-1][j] == '*':
cnt += 1
if matrix[i+1][j-1] == '*':
cnt += 1
if matrix[i-1][j-1] == '*':
cnt += 1
elif i == row-1 and 0 < j < col-1:
if matrix[i][j-1] == '*':
cnt += 1
if matrix[i-1][j] == '*':
cnt += 1
if matrix[i][j+1] == '*':
cnt += 1
if matrix[i-1][j+1] == '*':
cnt += 1
if matrix[i-1][j-1] == '*':
cnt += 1
print(cnt, end='')
else:
print(matrix[i][j], end='')
print()
지뢰찾기 구간을 9개로 나눠서 각 경우의 수에 해당하는 코드들을 다 작성했다. 더 간단하고 효율적으로 작성할 수 있는 방법을 생각해봐야 겠다.
'Project H4C Study Group' 카테고리의 다른 글
[Project H4C] 파이썬 코딩도장(9) (0) | 2021.01.28 |
---|---|
[Project H4C] 파이썬 코딩도장(8) (0) | 2021.01.26 |
[Project H4C] 파이썬 코딩도장(6) (0) | 2021.01.25 |
[Project H4C] 파이썬 코딩도장(5) (0) | 2021.01.23 |
[Project H4C] 파이썬 코딩도장(4) (0) | 2021.01.21 |