민주의네모들

[python] 2차원 리스트 생성 및 입력 받기, 원하는 값 찾기, 탐색, 전치 행렬 본문

Algorithm Study

[python] 2차원 리스트 생성 및 입력 받기, 원하는 값 찾기, 탐색, 전치 행렬

mjoooo 2020. 1. 23. 15:44
반응형

'본 포스팅은 글쓴이 개인의 공부 목적이므로, 틀린 부분이 있다면 댓글로 달아주시면 감사하겠습니다.'

 

오늘은 2차원 리스트에 대해 알아보겠다.

1. 2차원 리스트의 구조

2차원 리스트는 1차원 리스트를 묶어놓은 구조로,

많이 사용되는 자료구조 중 하나이다.

 

2차원 리스트의 선언은 세로길이(행의 개수), 가로길이(열의 개수)를 필요로 한다.

  ex) 2행 4열의 2차원 리스트

      a=[[0,1,2,3],[4,5,6,7]]

0 1 2 3
4 5 6 7

이제 리스트를 선언하고 초기화 하는 방법에 대해 알아보자.

 

2. 리스트 초기화

arr=[0,0,0,0,0]
arr=[0]*5
arr=[i for i in range(2,9) if i%2==0] #[2,4,6,8]

brr=[[1,2,3],[1,2,3],[1,2,3]]
brr=[[1,2,3]]*3
brr=[[1,2,3] for i in range(3)]
brr=[[i,j] for i in range(3) for j in range(2)] #[[0,0],[0,1],[1,0],[1,1],[2,0],[2,1]]

1차원 리스트 arr는 1~3줄과 같은 여러 가지 방법으로 초기화 및 선언이 가능하다.

특히 3째 줄과 같은 경우에는 python에서 리스트를 생성할 때 편리하게 사용할 수 있는

'List Comprehension'이라는 방법을 사용하였다.

     ** List Comprehension이란, [출력표현식 for 요소 in 입력Sequence [if 조건식]]과 같은 문법을 가지며

        '입력 sequence 안의 요소 중 if 조건식에 해당하는 출력표현식'을 리스트 형태로 빌드하는 것이라고

        해석할 수 있다. 더욱 자세한 내용은 아래의 링크를 참조하자.

2020/01/30 - [Algorithm Study] - [python] List Comprehension과 Generator Expression

 

[python] List Comprehension과 Generator Expression

'본 포스팅은 글쓴이 개인의 공부 목적이므로, 틀린 부분이 있다면 댓글로 달아주시면 감사하겠습니다.' 1. List Comprehension이란? 파이썬은 "list comprehension"이라는 개념을 지원한다. 이것은 쉽게 말해서,..

minjoos.tistory.com

 

2차원 리스트 brr 또한 5~8줄과 같은 여러 가지 방법으로 초기화 및 선언이 가능하다.

8째 줄의 경우에도 list comprehension을 사용하였다. 해석하자면, 0부터 2까지의 i와 0부터 1까지의 j로 만들 수 있는 [i,j]를 요소로 가지는 리스트를 brr로 빌드한 것이다.

 

이처럼 직접 타이핑하여 2차원 리스트를 선언 및 초기화하는 방법이 있다면,

데이터를 입력받아 2차원 리스트를 생성할 수도 있다.

 

3. 2차원 리스트 입력 받기

3 4

0 1 0 0

0 0 0 0

0 0 1 0

위와 같이 첫째 줄에 2차원 리스트의 행과 열이 주어지고, 둘째 줄부터 행렬의 데이터가 주어질 경우,

n,m=map(int, input().split())

#1
mylist=[0 for _ in range(n)]

for i in range(n):
    mylist[i]=list(map(int, input().split()))


#2
mylist=[]
for i in range(n):
    mylist.append(list(map(int, input().split())))


#3
mylist=[list(map(int, input().split())) for _ in range(n)]

먼저 input()함수로 입력받은 값을 split()로 쪼개고, map함수를 이용하여 int 자료형으로 변환하여 변수 n과 m에 담는다. (n=3, m=4)

이제 3가지 방법으로 2차원 리스트를 만들 수 있다.

 

#1

1차원 리스트인 mylist에 행의 개수(n)만큼의 0으로 채운다.

그다음 n번의 for문을 통해 한 줄씩 input값으로 받아서 mylist에 채워져있는 0을 입력받은 값으로 대체한다.

이 때도 map함수를 통해 int형으로 변환해준다.

 

#2

비어있는 1차원 리스트인 mylist를 선언하고,

n번의 for문을 통해 한 줄씩 입력받은 값을 mylist에 추가하는 방식이다.

append를 통해 한 줄씩 순서대로 리스트의 원소로 추가한다.

 

#3

위에 나온 선언, 초기화, 입력받고, 원소로 추가하는 방법을 한 줄로 축약한 것이다.

앞서 나왔던 list comprehension을 통해 mylist의 원소가 될 형식을 list(map(int, input().split())) 로 지정해주고,

n번만큼 시행한다.

 

위 방법 중 어느 방법을 쓰더라도, 아래와 같이 mylist가 생성된다.

 

4. 2차원 리스트에서 원하는 데이터의 위치 찾기

 

그렇다면 2차원 리스트에서 원하는 데이터 [행, 열]의 위치를 찾고 싶으면 어떻게 해야될까?

n,m=map(int, input().split())

#1
newlist=[]
mylist=[0 for _ in range(n)]
for i in range(n):
    mylist[i]=list(map(int, input().split()))
    for j in range(m):
        if mylist[i][j]==1:
            newlist.append([i,j])

#2
mylist=[list(map(int, input().split())) for _ in range(n)]
newlist=[(i,j) for i in range(n) for j in range(m) if mylist[i][j]==1]

위 코드는 2차원 리스트를 입력받고, 1이 입력된 [행, 열]의 위치를 찾는 두가지 방법을 써놓은 것이다.

 

#1

첫번째 방법은 for문을 이용해 일일이 비교하는 것이다.

먼저 newlist라는 새로운 리스트를 생성한다. 이 리스트에는 우리가 원하는 결과인 1이 입력된 [행, 열]의 위치를 넣을 것이다.

그리고 중첩 for문을 통해 i는 0부터 n-1까지(행의 개수만큼), j는 0부터 m-1까지(열의 개수만큼) 돌아가며 

mylist에 입력값을 넣고, 그 입력값에 1과 일치하는 값이 있는지 확인한다.

1과 일치하는 값이 있을 경우, newlist에 그 값의 위치인 [i, j]를 추가한다.

 

#2

두번째 방법은 List Comprehension을 이용하는 것이다. 

[(i,j) for i in range(n) for j in range(m) if mylist[i][j]==1] 를 해석해보자면, 

mylist의 원소 중, mylist[i][j]의 값이 1일 경우에는 (i, j)를 원소로 추가한다. (이 때, i는 0~n-1, j는 0~m-1)

 

5. 한 좌표의 상하좌우값 탐색

 

2차원 리스트의 한 좌표에서 인접 리스트 요소(상하좌우 값)를 탐색하고 싶을 때 사용하는 방법은 다음과 같다.

dx=[0,0,-1,1] #상하좌우
dy=[-1,1,0,0]
#델타 값을 이용하여 특정 원소의 상하좌우에 위치한 원소에 접근할 수 있음

for x in range(len(arr)):
    for y in range(len(arr[x])):
        for i in range(4):
            testX=x+dx[i]
            testY=y+dy[i]
            print(arr[testX][testY])

델타 값(dx, dy)은 한 좌표에서 네 방향의 좌표와 x, y의 차이를 저장한 리스트이다.

델타 값을 이용하여 특정 원소의 상하좌우에 위치한 원소에 접근할 수 있다.

 

    ** 2차원 리스트의 가장자리 원소들은 상하좌우 네 방향에 원소가 존재하지 않을 경우가 있으므로, 

        Index를 체크하거나 Index의 범위를 제한해야 한다.

 

6. 전치 행렬

 

전치 행렬이란 행과 열의 값이 반대인 행렬을 의미한다.

예를들어

1 2 3
4 5 6
7 8 9

의 전치 행렬은

1 4 7
2 5 8
3 6 9

이다.

쉽게 생각하면, 1 5 9의 대각선을 기준으로 접어서 맞닿는 부분의 값을 교환한 것이라고 생각하면 된다.

전치 행렬을 구현하는 코드는 다음과 같다.

arr=[[1,2,3],[4,5,6],[7,8,9]]

for i in range(3):
    for j in range(3):
        if i<j:
            arr[i][j], arr[j][i]==arr[j][i], arr[i][j]

2차원 행렬인 arr의 행(i) 열(j)의 좌표를 바꾸어 값을 교환하면 된다.

 

반응형

'Algorithm Study' 카테고리의 다른 글

[python] List Comprehension과 Generator Expression  (0) 2020.01.30