

,)로 구분# 가로2, 세로3의 2차원 리스트
>>> a = [[10, 20], [30, 40], [50, 60]]
>>> a
[[10, 20], [30, 40], [50, 60]]
# 알아보기 쉽게 3줄로 입력해도 무방
a = [[10, 20],
[30, 40],
[50, 60] ]
[])를 두 번 사용하며 [] 안에 세로(row) 인덱스와 가로(column) 인덱스를 지정>>> a = [[10, 20], [30, 40], [50, 60]]
>>> a[0] [0] # 세로 인덱스 0, 가로 인덱스 0인 요소 출력
10
>>> a[1][1] # 세로 인덱스 1, 가로 인덱스 1인 요소 출력
40
>>> a[2][1] # 세로 인덱스 2, 가로 인덱스 0인 요소 출력
60
>>> a[0][1] = 1000 # 세로 인덱스 0, 가로 인덱스 1인 요소에 값 할당
>>> a[0][1]
1000

📎 참고) 톱니형 리스트
파이썬에서는 가로 크기가 불규칙한 톱니형 리스트(jagged list)도 만들 수 있다.# 가로 크기(행의 요소 개수) 가 제각각 a = [[10, 20], [500, 600, 700], [9], [30, 40], [8], [800, 900, 1000]] # append 메서드를 사용하여 생성 >> a = [] >> a.append([]) >> a[0].append(10) >> a[0].append(20) >> a.append([]) >> a[1].append(500) >> a[1].append(600) >> a[1].append(700) >> a [[10, 20], [500, 600, 700]]
📎 참고) 2차원 튜플
튜플 안에 튜플을 넣는 방식, 튜플 안에 리스트를 넣는 방식, 리스트 안에 튜플을 넣는 방식 등이 가능
- 튜플 = ((값, 값), (값, 값), (값, 값))
- 튜플 = ([값, 값], [값, 값], [값, 값])
- 리스트 = [(값, 값), (값, 값), (값, 값)]
a = ((10, 20), (30, 40), (50, 60)) # 튜플 안에 튜플을 넣은 2차원 튜플 b = ([10, 20], [30, 40], [50, 60]) # 튜플 안에 리스트를 넣음 c = [(10, 20), (30, 40), (50, 60)] # 리스트 안에 튜플을 넣음튜플은 내용 변경 불가
a[0][0] = 500 # 안쪽 튜플 변경할 수 없음. TypeError 발생 a[0] = (500, 600) # 바깥쪽 튜플 변경할 수 없음. TypeError 발생 b[0][0] = 500 # 안쪽 리스트 변경할 수 있음 b[0] = (500, 600) # 바깥쪽 튜플 변경할 수 없음. TypeError 발생 c[0][0] = 500 # 안쪽 튜플 변경할 수 없음. TypeError 발생 c[0] = (500, 600) # 바깥쪽 리스트 변경할 수 있음
📎 참고) 알아보기 쉽게 출력하기
2차원 리스트를 출력하면 한 줄로 쭉 붙어서 출력된다.>> a = [[10, 20], [30, 40], [50, 60]] >> a [[10, 20], [30, 40], [50, 60]]2차원 리스트의 사각형 구조를 유지하도록 출력하려면
pprint모듈의pprint함수를 사용>> from pprint import pprint >> pprint(a, indent=4, width=20) # indent는 들여쓰기 칸 수, width는 가로 폭 [ [10, 20], [30, 40], [50, 60]]
for x, y in a:와 같이 in 앞에 변수를 두 개 지정해주면 가로 한 줄(안쪽 리스트)에서 요소 두 개를 꺼낸다.in 앞에 변수의 개수는 2차원 리스트에서 가로 크기(안쪽 리스트의 요소 개수)와 일치해야 한다.>>> a = [[10, 20], [30, 40], [50, 60]]
>>> for x, y in a: # 리스트의 가로 한 줄(안쪽 리스트)에서 요소 두 개를 꺼냄
print(x, y)
# 실행결과
10 20
30 40
50 60

for i in a:는 전체 리스트에서 가로 한 줄씩 꺼낸다.(안쪽 리스트를 통째로 꺼내 옴)for j in i:와 같이 가로 한 줄(안쪽 리스트) i에서 요소를 하나씩 꺼낸다.a = [[10, 20], [30, 40], [50, 60]]
for i in a: # a에서 안쪽 리스트를 꺼냄
for j in i: # 안쪽 리스트에서 요소를 하나씩 꺼냄
print(j, end=' ')
print()
# 실행결과
10 20
30 40
50 60

for range에 세로 크기와 가로 크기를 넣으면 인덱스로 사용 가능len으로 2차원 리스트 a의 크기를 구하면 리스트 안에 들어있는 모든 요소의 개수가 아니라 안쪽 리스트의 개수(세로 크기)가 나온다.len으로 안쪽 리스트 a[i]의 크기를 구해야 안쪽 리스트에 들어있는 요소의 개수(가로 크기)가 나온다.a = [[10, 20], [30, 40], [50, 60]]
for i in range(len(a)): # 세로 크기
for j in range(len(a[i])): # 가로 크기
print(a[i][j], end=' ')
print()
# 실행결과
10 20
30 40
50 60
for i in range(len(a)): # 세로 크기
for j in range(len(a[i])): # 가로 크기
len(a)도 2차원 리스트의 크기를 구했으니 안쪽 리스트의 개수(세로 크기)가 나온다.a = [[10, 20], [30, 40], [50, 60]]
i = 0
while i < len(a): # 반복할 때 리스트의 크기 활용(세로 크기)
x, y = a[i] # 요소 두 개를 한꺼번에 가져오기
print(x, y)
i += 1 # 인덱스를 1 증가시킴
# 실행결과
10 20
30 40
50 60
while i < len(a):와 같이 세로 크기만큼 반복하면서while j < len(a[i]):와 같이 가로 크기(안쪽 리스트의 요소 개수, len(a[i]))만큼 반복a = [[10, 20], [30, 40], [50, 60]]
i = 0
while i < len(a): # 세로 크기
j = 0
while j < len(a[i]): # 가로 크기
print(a[i][j], end=' ')
j += 1 # 가로 인덱스를 1 증가시킴
print()
i += 1 # 세로 인덱스를 1 증가시킴
# 실행결과
10 20
30 40
50 60
i += 1을 안쪽 while에서 수행하면 반복이 제대로 되지 않으므로 주의🔎i = 0
while i < len(a):
j = 0
while j < len(a[i]):
print(a[i][j], end=' ')
j += 1
i += 1 # 안쪽 while에서 i를 증가시키면 안 됨. 잘못된 방법
print()
for반복문으로 10번 반복하면서 append로 요소를 추가a = [] # 빈 리스트 생성
for i in range(10):
a.append(0) # append로 요소 추가
print(a)
# 실행결과
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
a = [] # 빈 리스트 생성
for i in range(3):
line = [] # 안쪽 리스트로 사용할 빈 리스트 생성
for j in range(2):
line.append(0) # 안쪽 리스트에 0 추가
a.append(line) # 전체 리스트에 안쪽 리스트를 추가
print(a)
# 실행결과
[[0, 0], [0, 0], [0, 0]]
[0 for j in range(2)]로 0을 2번 반복하여 [0, 0]으로 만들고for i in range(3)으로 [0, 0]을 3번 반복하여 [[0, 0], [0, 0], [0, 0]]으로 만든다.>>> a = [[0 for j in range(2)] for i in range(3)]
>>> a
[[0, 0], [0, 0], [0, 0]]
for반복문을 한 번만 사용 : 식 부분에서 리스트 자체를 곱해주면 된다.>>> a = [[0] * 2 for i in range(3)]
>>> a
[[0, 0], [0, 0], [0, 0]]
for로 반복하면 가로 크기를 꺼내면서 반복for반복문 안에서 다시 for로 꺼낸 가로 크기 i만큼 반복하면서 append로 요소 추가line을 추가a = [3, 1, 3, 2, 5] # 가로 크기를 저장한 리스트
b = [] # 빈 리스트 생성
for i in a: # 가로 크기를 저장한 리스트로 반복
line = [] # 안쪽 리스트로 사용할 빈 리스트 생성
for j in range(i): # 리스트 a에 저장된 가로 크기만큼 반복
line.append(0)
b.append(line) # 리스트 b에 안쪽 리스트를 추가
print(b)
# 실행결과
[[0, 0, 0], [0], [0, 0, 0], [0, 0], [0, 0, 0, 0, 0]]
>>> a = [[0] * i for i in [3, 1, 3, 2, 5]]
>>> a
[[0, 0, 0], [0], [0, 0, 0], [0, 0], [0, 0, 0, 0, 0]]
📎 참조) sorted로 2차원 리스트 정렬하기
2차원 리스트를 정렬할 때는sorted함수를 사용
- sorted(반복가능한객체, key=정렬함수, reverse=True 또는 False)
students = [ ['john', 'C', 19], ['maria', 'A', 25], ['andrew', 'B', 7] ] print(sorted(students, key=lambda student: student[1])) # 안쪽 리스트의 인덱스 1을 기준으로 정렬 print(sorted(students, key=lambda student: student[2])) # 안쪽 리스트의 인덱스 2를 기준으로 정렬# 실행결과 [['maria', 'A', 25], ['andrew', 'B', 7], ['john', 'C', 19]] [['andrew', 'B', 7], ['john', 'C', 19], ['maria', 'A', 25]]
student[1]은 안쪽 리스트의 인덱스 1을 뜻하며 'A', 'B', 'C' 순으로 정렬student[2]는 안쪽 리스트의 인덱스 2를 뜻하며 7, 19, 25 순으로 정렬
📎참고)풀잎스쿨 진행 중 남철님 추가 예제 부분
# 기본 문법 print(sorted(순회가능한 객체, key= 함수)) # 순회가능한 객체(iterable) : list, tuple 등. # 함수 : 정렬 기준 # 작동 순서 1. 함수에 순회가능한 객체의 요소들을 차례로 인자로 전달한다. 2. 전달받은 인자를 사용하여 반환받은 값들을 기준으로 '오름차순' 정렬한다. 3. 정렬한 순서로 순회가능한 객체의 요소를 리스트로 반환한다. 예) >> str_list = ['좋은하루','good_morning','굿모닝','niceday'] >> print(sorted(str_list, key=len)) # 함수 ['굿모닝', '좋은하루', 'niceday', 'good_morning']# 풀이 1. len 함수에 str_list 의 요소들을 차례로 인자로 전달한다. len('좋은하루') -> len('good_morning') -> len('굿모닝') -> len('niceday') 2. 전달받은 인자를 사용하여 반환받은 값들을 기준으로 오름차순 정렬한다. 반환값들 : 4 , 12 , 3 , 7 오름차순 정렬 : 3, 4, 7, 12 반환 하는 리스트 : ['굿모닝', '좋은하루', 'niceday', 'good_morning']람다 예) >> str_list = ['좋은하루','good_morning','굿모닝','niceday'] >> print(sorted(str_list, key=lambda x : x[1])) ['niceday', 'good_morning', '굿모닝', '좋은하루']#풀이 # lambda 매개변수 : 표현식 1. lambda x : x[1] 함수에 str_list 의 요소들을 차례로 인자로 전달한다. x = '좋은하루' -> x = 'good_morning' -> x = '굿모닝' -> x = 'niceday' 2. 전달받은 인자를 사용하여 반환받은 값들을 기준으로 오름차순 정렬한다. 반환값(표현식): x[1] : '은', x[1] : 'o' , x[1] : '모', x[1] : 'i' 오름차순 정렬 : 'i' , 'o', '모', '은' 반환하는 리스트 : ['niceday', 'good_morning', '굿모닝', '좋은하루']
copy 메서드로 b에 복사한 뒤 b의 요소를 변경해보면 리스트 a와 b에 모두 반영 >>> a = [[10, 20], [30, 40]]
>>> b = a
>>> b[0][0] = 500
>>> a
[[500, 20], [30, 40]]
>>> b
[[500, 20], [30, 40]]

>>> a = [[10, 20], [30, 40]]
>>> b = a.copy()
>>> b[0][0] = 500
>>> a
[[500, 20], [30, 40]] # 리스트 a에도 반영
>>> b
[[500, 20], [30, 40]] # 객체는 서로 다르다.🔎

copy 메서드 대신 copy 모듈의 deepcopy 함수를 사용copy.deepcopy 함수 : 중첩된 리스트(튜플)에 들어있는 모든 리스트(튜플)를 복사하는 깊은 복사(deep copy)를 해준다.>>> a = [[10, 20], [30, 40]]
>>> import copy # copy 모듈을 가져옴
>>> b = copy.deepcopy(a) # copy.deepcopy 함수를 사용하여 깊은 복사
>>> b[0][0] = 500
>>> a
[[10, 20], [30, 40]]
>>> b
[[500, 20], [30, 40]]

다음 소스 코드를 완성하여 높이 2, 세로 크기 4, 가로 크기 3인 3차원 리스트를 만드세요(리스트 표현식 사용).
a = [_____________________]
print(a)
# 실행결과
[[[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 for col in range(3)] for row in range(4)] for depth in range(2)]
3차원 리스트의 형태

즉, 가로×세로 평면(2차원 리스트)이 여러 겹 있는 모양
따라서 한 면을 완성한 뒤 다른 면을 완성하는 방식으로 작성
리스트 표현식으로 세로 4, 가로 3인 2차원 리스트를 만들기
[[0 for col in range(3)] for row in range(4)]
여러 번 반복해주면 3차원 리스트가 된다.
여기서는 높이가 2라고 했으므로 for depth in range(2)와 같이 반복
이때 2차원 리스트가 다시 안쪽 리스트가 될 수 있도록 [ ]로 묶어준다.
[[[0 for col in range(3)] for row in range(4)] for depth in range(2)]