파이썬 2차원 리스트 생성, 요소 접근, 반복문으로 출력, 할당, 복사

Yeonu·2020년 11월 19일
0

Python 이론

목록 보기
10/30
post-thumbnail
post-custom-banner

2차원 리스트는 행, 열(세로, 가로) 순으로 접근한다.

2차원 리스트


리스트 안에 리스트를 넣어서 만들 수 있다.
리스트 = [[값, 값], [값, 값], [값, 값]]

>>> a = [[10, 20], [30, 40], [50, 60]]
>>> a
[[10, 20], [30, 40], [50, 60]]

가독성을 위해 세로로 입력해도 된다.



2차원 리스트의 요소에 접근하기

리스트[세로인덱스][가로인덱스]
리스트[세로인덱스][가로인덱스] = 값

>>> a = [[10, 20], [30, 40], [50, 60]]
>>> a[2][1]           # 세로 인덱스 2, 가로 인덱스 0인 요소 출력
60
>>> a[0][1] = 1000    # 세로 인덱스 0, 가로 인덱스 1인 요소에 값 할당
>>> a[0][1]
1000

가로 크기(행의 요소 개수)가 불규칙한 톱니형 리스트(jagged list)도 만들 수 있다. append메서드 등을 사용해 동적으로 생성 가능하다.

2차원 튜플. 다양한 방식이 가능하다.
튜플 = ((값, 값), (값, 값), (값, 값))
튜플 = ([값, 값], [값, 값], [값, 값])
리스트 = [(값, 값), (값, 값), (값, 값)]



for문으로 2차원 리스트 요소 출력하기

  1. for문 한 번 쓰기

    >>> a = [[10, 20], [30, 40], [50, 60]]
    >>> for x, y in a:    # 리스트의 가로 한 줄(안쪽 리스트)에서 요소 두 개를 꺼냄
    ...     print(x, y)
    ...
    10 20
    30 40
    50 60
  2. for문 두 번 쓰기

    a = [[10, 20], [30, 40], [50, 60]]
    
    for i in a:        # a에서 안쪽 리스트를 꺼냄
        for j in i:    # 안쪽 리스트에서 요소를 하나씩 꺼냄
            print(j, end=' ')
        print()
  3. range 사용하기

    a = [[10, 20], [30, 40], [50, 60]]
    
    for i in range(len(a)):            # 세로 크기
        for j in range(len(a[i])):     # 가로 크기 a[i] [값, 값]의 len은 2
            print(a[i][j], end=' ')
        print()
  4. while문 한 번 쓰기

    a = [[10, 20], [30, 40], [50, 60]]
    
    i = 0
    while i < len(a):    # 반복할 때 리스트의 크기 활용(세로 크기)
        x, y = a[i]      # 요소 두 개를 한꺼번에 가져오기
        print(x, y)
        i += 1           # 인덱스를 1 증가시킴
  5. while문 두 번 쓰기

    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 증가시킴



반복문으로 2차원 리스트 만들기

a = []    # 빈 리스트 생성

for i in range(3):
    line = []              # 안쪽 리스트로 사용할 빈 리스트 생성
    for j in range(2):
        line.append(0)     # 안쪽 리스트에 0 추가
    a.append(line)         # 전체 리스트에 안쪽 리스트를 추가

print(a)



리스트 표현식(comprehension)으로 2차원 리스트 만들기

>>> a = [[0 for j in range(2)] for i in range(3)] # 바깥 for문을 뒤에
>>> a
[[0, 0], [0, 0], [0, 0]]

더 간단한 방법
0이 1개 들어있는 리스트 [0]에 2를 곱하면 [0, 0]이 되는데,
이걸 for i in range(3)으로 3번 반복해주면 [[0, 0], [0, 0], [0, 0]]이 된다.

>> a = [[0] * 2 for i in range(3)]
>> a
  [[0, 0], [0, 0], [0, 0]]



톱니형 리스트 만들기

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)

마찬가지로 더 간단하게 생성 가능하다.

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



2차원 리스트의 할당과 복사

2차원 리스트는 리스트와 달리 변수에 할당, copy() 모두 한 변수에서 요소를 변경하면 두 리스트에 모두 반영된다.

2차원 이상의 다차원 리스트는 리스트를 완전히 복사하려면 copy 메서드 대신 copy 모듈의 deepcopy 함수를 사용해야 한다.

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




@심사문제 23.7
표준 입력으로 2차원 리스트의 가로(col)와 세로(row)가 입력되고 그 다음 줄부터 리스트의 요소로 들어갈 문자가 입력됩니다. 이때 2차원 리스트 안에서 *는 지뢰이고 .은 지뢰가 아닙니다. 지뢰가 아닌 요소에는 인접한 지뢰의 개수를 출력하는 프로그램을 만드세요.

여러 줄을 입력 받으려면 다음과 같이 for 반복문에서 input을 호출한 뒤 append로 각 줄을 추가하면 됩니다(list 안에 문자열을 넣으면 문자열이 문자 리스트로 변환됩니다).

matrix = []
for i in range(row):
    matrix.append(list(input()))

위치(.)를 먼저 찾은 후, 인접한 8개 점들에 지뢰(*)가 있는지를 확인해서 있으면 하나씩 카운트하는 식으로 코드를 구현했습니다. 이때 조심해야하는 것은 8개 점들에 대해 조사할 때 인덱스를 벗어나지 않도록 적절한 조건들을 넣어주는 것입니다.

row, col = map(int, input().split()) # 세로 가로 입력받고
matrix = []
for i in range(row): # 세로 층만큼 돌면서 나머지 항목(., *) 입력받기
   matrix.append(list(input()))
print()
for i in range(row): # 세로 돌기
   for j in range(col): # 가로 돌기
       cnt = 0
       if matrix[i][j] == ".": # 만약 받은 요소가 지뢰가 아닐 때
           if i != 0 and j != 0: # 현재 요소가 처음 요소가(인덱스0) 아니면
               if matrix[i-1][j-1] == "*": cnt += 1 # 기준점 왼쪽 상단이 지뢰면 카운트
           if i != row-1 and j != col-1: # 현재 요소가 마지막 요소가 아니면
               if matrix[i+1][j+1] == "*": cnt += 1 # 기준점 오른쪽 하단이 지뢰면 카운트
           if i != 0: # 현재 요소가 첫 층이 아닐 때
               if matrix[i-1][j] == "*": cnt += 1 # 기준점 바로 상단이 지뢰면 카운트
           if i != 0 and j != col-1:
               if matrix[i-1][j+1] == "*": cnt += 1
           if j != 0:
               if matrix[i][j-1] == "*": cnt += 1
           if i != row - 1 and j != 0:
               if matrix[i+1][j-1] == "*": cnt += 1
           if j != col -1:
               if matrix[i][j+1] == "*": cnt += 1
           if i != row -1:
               if matrix[i+1][j] =="*": cnt += 1
           matrix[i][j] = cnt # 모두 확인하고 .자리에 주위 지뢰 cnt수 할당
           print(matrix[i][j], end="")
       else: #지뢰일 경우 일반 출력
           print(matrix[i][j], end="")
   print()
간결버전
row, col = map(int, input().split())
matrix = []
for i in range(row):
  matrix.append(list(input()))
print()
for i in range(row):
  for j in range(col):
      cnt = 0
      if matrix[i][j] == ".":
          for y in range(i-1, i+2): # 세로 돌기(i가 1일 경우만 모든 행 돈다.)
              for x in range(j-1, j+2): # 가로 돌기(위와 동일. j가 1일 때만 모든 열 돌기)
                  if not (y < 0 or x < 0 or y >= row or x >= col): # not(성립불가조건)으로 모든 요소에 지뢰 확인. (i,j가 1이 아닐 때 false로 if문 안탐. 애초에 위 두개의 for문에서 모든 행 확인 불가.)
                      if matrix[y][x] == "*": # 지뢰 있으면 카운팅
                          cnt += 1
          matrix[i][j] = cnt
          print(matrix[i][j], end="")
      else:
          print(matrix[i][j], end="")
  print()

참조 : https://bskyvision.com/909

post-custom-banner

0개의 댓글