,
)로 구분# 가로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)]