Python에서 작업하다 보면 단순한 리스트 대신 아이템들의 큐(queue)를 만들어야 하는 경우가 종종 있습니다. 예를 들어 컨퍼런스 등록 현황을 관리하는 프로그램을 작성한다고 가정해 봅시다. 새로운 참가자가 등록하면 대기열 맨 뒤에 추가하고, 앞쪽 사람들이 입장함에 따라 자신의 순서가 자연스럽게 앞당겨지도록 처리해야 합니다.
바로 이런 문제를 해결하기 위해 Python에는 queue라는 내장 라이브러리가 마련되어 있습니다. 큐는 스택(stack)과 비슷하지만 결정적인 차이가 있습니다. 큐에서는 가장 먼저 추가된 아이템을 먼저 제거하는 반면, 스택에서는 가장 최근에 추가된 아이템을 먼저 제거합니다.
이 글에서는 Python 큐의 기본 개념과 실제 구현 방법을 단계별로 살펴보겠습니다.
큐(Queue) 기초 개념
큐는 데이터를 넣은 순서 그대로 꺼내야 할 때 유용한 자료구조입니다. 앞선 컨퍼런스 예시처럼, 등록한 순서대로 줄을 서고 앞사람부터 차례로 입장하는 상황을 떠올리면 쉽게 이해할 수 있습니다.
큐는 배열이나 일반 리스트와 달리 무작위 접근(random access)이 불가능합니다. 즉, 큐에 저장된 데이터는 항상 특정한 순서를 유지합니다. 새 아이템을 추가하면 항상 맨 뒤에 삽입되고, 제거할 때는 항상 맨 앞의 아이템이 빠집니다. 이러한 방식을 FIFO(First-In, First-Out, 선입선출)라고 부릅니다.
Python에서는 표준 리스트(list)를 큐처럼 사용할 수도 있습니다. 하지만 리스트의 앞부분에서 요소를 삽입하거나 삭제할 때마다 나머지 모든 요소를 한 칸씩 이동시켜야 하기 때문에 성능이 크게 저하될 수 있습니다. 따라서 선입선출 방식의 처리가 필요하다면 전용 큐 자료구조를 사용하는 것이 좋습니다.
Python Queue 사용법
그렇다면 Python에서 큐는 어떻게 구현할까요? 내장 라이브러리인 queue 모듈을 활용하면 됩니다. 이 모듈에는 다양한 큐 관련 클래스가 포함되어 있지만, 이번 튜토리얼에서는 가장 기본이 되는 queue.Queue 클래스에 집중하겠습니다.
예시로, 지역 영화관에서 개봉한 최신 영화를 보고 싶어 하는 사람들을 관리하는 프로그램을 만든다고 해보겠습니다. 영화 관람 대기자 명단을 큐로 관리하면 등록 순서를 손쉽게 유지할 수 있습니다.
먼저 큐 객체를 생성합니다.
from queue import Queue
waitlist = Queue()이제 put() 메서드를 사용해 큐에 데이터를 넣을 수 있습니다. 영화를 보기 위해 방금 등록한 다섯 명을 대기열에 추가해 보겠습니다.
waitlist.put('Erin')
waitlist.put('Samantha')
waitlist.put('Joe')
waitlist.put('Martin')
waitlist.put('Helena')다섯 명의 이름이 모두 큐에 추가되었습니다. Erin이 첫 번째, 그다음이 Samantha이며, Helena가 마지막입니다. get() 메서드를 호출해 직접 확인해 보겠습니다.
print(waitlist.get())실행 결과:
Erin가장 먼저 등록한 Erin이 첫 번째로 출력되었습니다. 큐에서 처음 두 명의 이름을 꺼내려면 get() 메서드를 두 번 호출하면 됩니다.
print(waitlist.get())
print(waitlist.get())실행 결과:
Erin
SamanthaPython Deque 활용 예제
그렇다면 큐의 양쪽 끝에서 모두 요소를 추가하거나 제거하고 싶다면 어떻게 해야 할까요? 바로 이럴 때 deque(double-ended queue, 덱)가 필요합니다. deque를 사용하면 큐의 시작점과 끝점 양쪽에서 자유롭게 요소를 추가·제거할 수 있는 양방향 큐를 만들 수 있으며, 후입선출(LIFO) 방식으로도 활용할 수 있습니다.
앞서 사용한 영화 대기자 명단 예제를 그대로 활용해 보겠습니다. 먼저 deque 객체를 선언합니다.
from collections import deque
waitlist = deque()deque가 초기화되었으니, 이제 대기자 이름들을 추가해 보겠습니다.
waitlist.append('Erin')
waitlist.append('Samantha')
waitlist.append('Joe')
waitlist.append('Martin')
waitlist.append('Helena')여기서는 append() 메서드를 사용해 큐에 아이템을 하나씩 추가했습니다. 저장된 값을 확인하려면 다음 코드를 실행하세요.
print(waitlist)실행 결과:
deque(['Erin', 'Samantha', 'Joe', 'Martin', 'Helena'])입력한 순서 그대로 데이터가 저장된 것을 확인할 수 있습니다. 그렇다면 큐의 첫 번째 아이템을 제거하려면 어떻게 할까요? popleft() 메서드를 사용하면 됩니다.
waitlist.popleft()
print(waitlist)첫 번째 아이템인 Erin이 제거되고 다음과 같은 결과가 출력됩니다.
deque(['Samantha', 'Joe', 'Martin', 'Helena'])deque의 모든 아이템을 한 번에 비우고 싶다면 clear() 메서드를 사용하세요.
waitlist.clear()
print(waitlist)실행 결과:
deque([])deque 안의 데이터는 모두 사라졌지만, 객체 자체는 여전히 존재하므로 이후에 계속 재사용할 수 있습니다.
마무리
지금까지 큐가 무엇인지, 그리고 FIFO(선입선출) 방식으로 데이터를 관리하는 자료구조를 어떻게 구현하는지 살펴보았습니다. 신제품 출시 시 대기자 명단을 관리하는 것처럼, 큐는 순서가 중요한 다양한 상황에서 활용할 수 있습니다.
또한 collections.deque를 사용하면 양쪽 끝에서 자유롭게 요소를 추가·제거할 수 있는 양방향 큐를 손쉽게 만들 수 있다는 점도 배웠습니다. 이제 여러분도 직접 큐와 deque를 활용한 코드를 작성할 준비가 되었습니다!