파이썬 자료구조 스택(Stack) 큐(Queue) 개념, 리스트 append pop 실습

지난 시간에 파이썬의 기본적인 조건문반복문을 어떻게 사용하는지에 대해 공부했다. 이번에는 자료 구조에 대한 개념을 살펴본다.

초보 수준에서 끽해야 몇개, 몇십개 정도의 데이터를 만지며 연습하는 거라면 상관이 없지만 실무에서 수기가 수테라 이상의 데이터를 관리해야 되는 상황에서는 자원을 효율적으로 사용하고 속도를 올리는 것도 매우 중요해진다. 따라서 파이썬의 자료 구조에 대해 이해하고 보다 효율성 있는 프로그래밍 코드를 짜는 실력을 갖추어야 겠다.

먼저 파이썬 자료구조에서 스택(Stack)과 큐(Queue)의 개념에 대해 알아본다.

스택 (Stack)

스택이란 나중에 넣은 데이터가 먼저 반환되도록 설계한 메모리 구조를 말한다. Last In First Out (LIFO) 라고도 한다.

스택 구조에서 데이터의 입력은 Push라 부르고 데이터의 출력은 Pop이라 칭한다.

스택

이런식으로 새롭게 들어가는 데이터를 맨 위에 쌓았다가, 불러올 때는 맨 위에서 불러온다고 해서 스택이라는 이름이 붙었다. 더미로 쌓았다는 뜻으로.

파이썬에서의 스택(Stack)

파이썬에서는 자료형 중에 리스트를 사용하여 스택 구조로 데이터를 처리할 수 있다. 리스트에 데이터의 입출력하려면 아래와 같은 함수를 사용한다.

  • 데이터의 입력 : push → append()
  • 데이터의 출력 : pop → pop()

주의해야 할 것은 pop은 데이터 구조에서 맨 마지막에 있는 값을 뽑아서 준다고 이해하면 된다. 즉 반환값이 있는, 리턴 (Return) 시켜주는 함수이다. pop으로 뽑아낸 데이터는 원래 리스트 내에서 없어진다.

리스트에 append와 pop을 사용시 어떻게 변하는지 아래 내용을 참고하여 실습해보자.

>>> a=[1,2,3,4,5]      ## 리스트 a 선언
>>> a.append(6)        ## a에 데이터 추가
>>> a                  ## a 확인
[1, 2, 3, 4, 5, 6]     ## 6이 마지막에 추가됨
>>> a.append(7)        ## a에 데이터 추가
>>> a                  ## a 확인
[1, 2, 3, 4, 5, 6, 7]  ## 7이 마지막에 추가됨
>>> a.pop()            ## a에서 데이터 출력
7                      ## 마지막 7이 출력됨
>>> a                  ## a 확인
[1, 2, 3, 4, 5, 6]     ## 마지막 데이터가 사라짐
>>> a.pop()            ## a에서 데이터 출력
6                      ## 마지막 6이 출력됨
>>> a                  ## a 확인
[1, 2, 3, 4, 5]        ## 마지막 데이터가 사라짐
>>> b=a.pop()          ## 마지막 데이터를 b에 저장
>>> a                  ## a 확인
[1, 2, 3, 4]           ## 마지막 데이터가 사라짐
>>> b                  ## b 확인
5                      ## 마지막 데이터가 b에 할당됨

pop으로 데이터를 뽑아내면 원래 리스트에 있던 데이터 중 마지막 요소가 사라지는 점에 주목하자. 

이를 이용해서 입력받은 메세지를 역순으로 출력하는 코드를 만들어 볼 수 있다.

## 코드

message=input("input any message :") 
message_list=list(message) 
print(message_list)
for i in range(len(message_list)):
    print(message_list.pop())
    print(message_list)


## 결과

['a', 'b', 'c', 'd', 'e']
e
['a', 'b', 'c', 'd']
d
['a', 'b', 'c']
c
['a', 'b']
b
['a']
a
[]

input을 통해 abcde를 입력하면 list() 를 이용해서 각 글자를 하나의 원소(element)로 삼는 리스트 자료형 형태로 변환한다.

그리고 range(len(message_list)) 리스트의 길이만큼 range를 설정하였다. abcde를 입력시 len(message_list)=5가 되고 따라서 range(0,5)로 설정이 된다. range(0,5)는 0부터 4까지라는 의미이므로 for문을 총 5번 반복수행하게 된다.

pop으로 맨 끝의 원소(element)를 뽑아내서 출력하고 리스트를 확인, 이것을 원소 개수만큼 반복하도록 만든 코드이다.

큐 (Queue)

큐는 줄이라는 의미인데, 파이썬 자료구조에서의 큐는 말그대로 먼저 줄 선 데이터가 먼저 반환되도록 한다는 의미이다. 선입선출, First In First Out (FIFO) 라고도 한다. 스택(Stack)과 반대되는 개념이다.

큐

이렇게 새로 들어간 데이터는 뒤에 붙이지만 출력은 앞에서부터 하는 식이다. 

파이썬에서의 큐(Queue)

파이썬에서의 큐 역시 리스트를 이용한다. 큐에서는 데이터 입력은 스택과 동일하게 push라고 하고 출력은 get이라고 한다. 사용하는 함수는 스택에서와 같다.

  • 데이터의 입력 : push → append()
  • 데이터의 출력 : get → pop(0)

pop() 가 아니라 pop(0) 으로 바뀐 것을 볼 수 있다. 0을 넣어주면 0번째 즉 가장 앞의 원소를 뽑아낸다는 뜻이니까 선입선출을 하게 되는 것이다.

>>> a=[1,2,3,4,5]   ## 리스트 a 선언
>>> a.append(6)     ## 6 추가
>>> a               ## a 확인
[1, 2, 3, 4, 5, 6]  ## 맨 뒤에 6 추가됨
>>> a.pop(0)        ## 데이터 출력
1                   ## 제일 앞 원소 출력됨
>>> a               ## a 확인
[2, 3, 4, 5, 6]     ## 1 사라짐
>>> a.pop(0)        ## 데이터 출력
2                   ## 제일 앞 원소 출력됨
>>> a               ## a 확인
[3, 4, 5, 6]        ## 2 사라짐

뭐 아까 스택할때 했던것과 별반 다르지 않다. 다만 pop(0)을 해서 맨 앞의 원소를 뽑아낸 차이점만 있을 뿐이다. 여기서도 뽑아낸 후 원래 리스트에서는 원소가 사라지게 된다.

리스트의 인덱스는 맨 앞 원소부터 0,1,2,3,4…. 순으로 매겨지기 때문에 제일 앞의 원소를 뽑아낸 후에는 다시 0,1,2,3,4… 순으로 인덱스가 할당된다. 그래서 맨 앞의 원소를 또 뽑아내려면 역시 pop(0)을 해주어야 한다.

파이썬 자료구조에서 후입선출과 선입선출 두 가지 개념인 스택(Stack)과 큐(Queue)에 대해서 간단히 알아보았다.

실제로 지금 한 것처럼 append랑 pop을 이용해서 리스트를 직접 조작하면서 자료관리를 하는 경우는 거의 없다. 여기서는 개념을 이해하기 위한 간단한 실습을 해본 것이다. 스택과 큐가 이런거구나 정도로 알고 넘어가면 되겠다.

다음 시간에는 튜플, 셋, 딕셔너리 등 다른 자료구조에 대해서도 하나씩 공부해보자.