가득 찬 deque(maxlen=n)의 오른쪽에 append(x)하면 왼쪽 요소가 제거됩니다. 왼쪽에 appendleft(x)하면 오른쪽 요소가 제거됩니다. 새 값은 호출한 끝에 들어가고 초과 용량만큼 반대편 끝에서 밀려납니다.
maxlen은 저장할 최대 길이입니다. 가득 찬 상태의 append와 appendleft는 추가 방향의 반대 끝 항목을 제거하므로, 양끝 추가를 섞으면 최근 항목만 남는다고 볼 수 없습니다.
추가하는 쪽의 반대 끝 항목을 버립니다
collections.deque에 maxlen을 지정하면 항목 수의 상한을 둡니다. Python 3.12 문서는 길이가 제한된 deque가 가득 찬 상태에서 새 항목을 추가하면 반대쪽 끝의 항목을 버린다고 정의합니다. 메서드 이름과 추가 방향을 먼저 확인하면 무엇이 사라지는지 헷갈리지 않습니다. append는 오른쪽 끝에 추가하고, appendleft는 왼쪽 끝에 추가합니다. 따라서 두 메서드는 서로 반대 방향에서 기존 항목을 밀어냅니다.
오른쪽 append는 왼쪽의 1을 밀어냅니다
현재 deque가 [1, 2, 3]이고 maxlen=3이라고 하겠습니다. append(4)는 오른쪽 끝에 4를 넣으려 합니다. 네 값이 되어 상한을 넘기므로 반대쪽인 왼쪽 끝의 1이 빠지고 [2, 3, 4]가 남습니다. 반대로 처음 상태에서 appendleft(0)을 부르면 왼쪽 끝에 0이 들어가고 오른쪽 끝의 3이 빠져 [0, 1, 2]가 됩니다.
from collections import deque
right = deque([1, 2, 3], maxlen=3)
right.append(4)
print(list(right))
left = deque([1, 2, 3], maxlen=3)
left.appendleft(0)
print(list(left))| 초기 상태 | 연산 | 추가 위치 | 버리는 위치 | 최종 상태 |
|---|---|---|---|---|
| [1, 2, 3] | append(4) | 오른쪽 | 왼쪽의 1 | [2, 3, 4] |
| [1, 2, 3] | appendleft(0) | 왼쪽 | 오른쪽의 3 | [0, 1, 2] |
deque를 iterable로 초기화할 때도 같은 방향 규칙이 적용됩니다. 생성자는 입력 iterable을 왼쪽에서 오른쪽으로 읽으면서 오른쪽 append에 해당하는 방식으로 채웁니다. 그래서 deque([0, 1, 2, 3], maxlen=3)은 가장 최근에 오른쪽으로 들어온 세 값 [1, 2, 3]을 남깁니다. 이 결과는 입력을 모두 보관한 뒤 왼쪽 세 값을 자른다는 별도 규칙이 아니라, 오른쪽에 차례로 추가하면서 용량 초과 항목을 반대쪽에서 제거한 결과와 같습니다.
끝을 표시한 뒤 한 번에 한 연산씩 갱신합니다
- 현재 deque의 순서를 왼쪽에서 오른쪽으로 적습니다.
append인지appendleft인지 확인하고 새 값이 들어갈 끝을 표시합니다.- 현재 길이가
maxlen보다 작은지 가득 찼는지 확인합니다. - 가득 찼다면 새 항목과 반대쪽 끝을 짝지어 제거합니다.
- 다음 연산은 갱신된 상태에서 다시 시작합니다.
예를 들어 [2, 3, 4]에서 appendleft(1)을 실행하면 왼쪽에 1이 들어가고 반대편 오른쪽의 4가 제거되어 [1, 2, 3]이 됩니다. 연산을 여러 번 연속 적용한다면 각 단계마다 남은 deque를 다시 적으세요. 한 번 빠진 항목은 다음 연산에서 되돌아오지 않습니다. maxlen을 지정하지 않거나 None으로 두면 deque가 임의 길이까지 커질 수 있으므로, 자동 제거를 기대하려면 실제 제한 값이 설정되어 있는지도 확인해야 합니다.
maxlen을 인덱스나 자동 정렬로 오해하지 않습니다
흔한 실수는 maxlen=3을 ‘인덱스 3까지만 보관한다’고 읽거나, 새 값이 추가되면 언제나 왼쪽 항목이 빠진다고 외우는 것입니다. maxlen은 최대 길이이며 제거 방향은 호출한 추가 방향의 반대입니다. 또 appendleft는 값을 맨 앞에 두므로, 순서를 뒤집는 extendleft(iterable)과 같은 연산이라고 생각하면 안 됩니다. 단일 appendleft는 한 항목을 왼쪽에 넣고, extendleft는 iterable을 왼쪽에 차례로 추가하기 때문에 iterable 내부 순서가 결과에서 역전될 수 있습니다. 이번 문제에서는 한 번의 추가와 한 번의 제거에 집중하면 됩니다.
시험에서 deque가 이미 가득 찼다고 명시하지 않았다면 먼저 현재 길이와 maxlen을 비교해야 합니다. 공간이 남아 있을 때는 새 항목만 추가되고 기존 값은 제거되지 않습니다. 길이가 상한과 같을 때에만 반대쪽 끝에서 초과 항목이 사라집니다. 경계 상태를 구별하면 짧은 코드에서도 ‘추가’와 ‘밀어내기’가 발생하는 시점을 정확히 계산할 수 있습니다.
정답을 가리고 확인해 보세요
이 글을 위해 만든 학습 예시이며 공식 기출문제나 판매 카드의 인용이 아닙니다.
deque([4, 5, 6], maxlen=3)에서 appendleft(3)을 호출하면 어떤 값을 제거하고 어떤 순서가 남나요?
정답과 해설 확인
오른쪽 끝의 6을 제거하고[3, 4, 5]가 남습니다.appendleft는 왼쪽 끝에 새 값을 추가합니다. 가득 찬 bounded deque는 새 값이 들어온 쪽의 반대 끝에서 기존 항목을 제거합니다.