1. 핵심 개념
불필요한 변수 정리는 물론, 컬렉션 요소 제거 등 참조 해제 에 사용되는 예약어
→ 해당 이름(name)과 객체 간의 참조 관계 자체를 끊는 역할
- 값을 None 으로 만드는 것(= 참조를 다른 객체로 바꾸는 것) 과는 다름 (값 초기화 vs 참조 해제)
- 사용하지 않는 변수를 명시적로 제거
→ 해당 객체에 대한 참조를 줄이고 메모리 해제를 촉진
→ 대용량 데이터를 다루는 경우(ex. 대형 리스트, 데이터프레임, 이미지 데이터) 메모리 효율성에 도움 - 컨테이너 자료형 내부 요소 제거에 유용
→ 리스트, 딕셔너리, 사용자 정의 객체 에서 원하는 요소만 부분적으로 제거
ex) pop과 달리, 반환 없이 단순 삭제만 수행 - 슬라이싱으로 한번에 많은 요소 제거 가능 → 부분 수정 빠름
- 메모리 관리 최적화 (∵ 참조 해제, 추가 설명은 아래)
a = 10
del a # a라는 이름 더 이상 존재 X
※ 사용 시, 주의사항 (+ 흔한 오류)
- 불변 객체(문자열, 튜플) 에서의 요소 삭제는 불가
- 변수명 자체를 삭제 가능 ex) del x
이후, 변수 접근 시 NameError 발생
- 동일 객체를 참조 중이면 메모리 해제되지 않음
- 잘못된 인덱스, 존재하지 않는 키 삭제 시, IndexError, KeyError 발생 주의
- del의 주요 동작 원리
- del 변수명 : 변수 자체 제거(참조 해제)
- del 리스트[인덱스] : 해당 위치의 리스트 요소, 슬라이싱 삭제
- del 딕셔너리['키'] : 딕셔너리 키 + 해당 값 제거
- 중첩 자료 구조에서 부분 제거
- del 키워드와 메모리 관리
- 참조 해제는 객체 자체를 제거하는 것 이 아닌 이름과 객체의 연결을 해제
- 참조 카운트가 0 (= 객체를 참조하는 변수가 하나도 없을 때 ) 이 되어야 실제 메모리 해제
→ 메모리 해제되는 시점은 가비지 컬렉터(GC)에 의해 결정
import sys
x = [1, 2, 3]
print(sys.getrefcount(x)) # 출력 : 2 (getrefcount 호출 때문에 +1 됨)
y = x # 같은 객체를 y도 참조
print(sys.getrefcount(x)) # 출력 : 3
del x # x와 객체 참조 해제
print(sys.getrefcount(y)) # 출력 : 2 (y가 참조 중, 객체는 살아있음)
2. 요소 삭제 관련, del 키워드와의 비교
- 메서드 비교표
| del | pop() | remove() | |
| 삭제 대상 | 변수, 리스트 요소(인덱스), 슬라이스, 딕셔너리 키 | 리스트 요소 (= 인덱스 기반) | 리스트 요소 (= 값 기반) |
| 반환값 | 없음 | 삭제된 요소 반환 | 없음 |
| 삭제 기준 | 인덱스/슬라이스 또는 변수명 | 인덱스 | 값 |
| 주 용도 | 참조 해제, 변수/요소/슬라이스 삭제 | 요소를 꺼내면서 삭제 | 특정 값을 찾아 삭제 |
| 특징 | 반환 없음, 변수명 자체도 삭제 가능 | 요소를 가져오면서 삭제 가능 | 첫 번째 일치 값만 삭제 |
| 시간 복잡도 | O(N) (중간 삭제 시, 뒷 요소 이동 필요) | O(N) (중간 삭제 시, 뒷 요소 이동 필요) | O(N) (값 탐색 후 삭제) |
| 예시 | del arr[2] → 2번 요소 제거 |
arr.pop(2) → 2번 요소 제거 후 반환 |
arr.remove(10) → 값 10 제거 |
※ pop() 사용 시, 주의사항
- 인덱스 지정 안 하면 마지막 요소 삭제 후 반환 ex) pop() == pop(-1)
- 스택 자료구조처럼 활용 가능
※ remove() 사용 시, 주의사항
- 값이 존재하지 않으면 ValueError 발생
- 첫 번째 일치 값만 삭제, 중복 값은 한 번에 하나씩만 제거
- del vs = None
- 기존 객체에 대한 참조를 끊는다는 점에서 거의 동일
- 반환값 둘다 없음
- del 사용과 None 대입은 기존 객체 참조 카운트 1 감소 시킴
→ 마찬가지로 해당 객체의 다른 참조가 없으면 수거 대상 ( 참조 해제는 즉시, 실제 수거는 GC 시점 )
| del x | x = None | |
| 의미 | 이름 (변수) 자체를 삭제 | 이름을 None 객체로 다시 바인딩 |
| 일반적 용도 | - 이름/요소를 아예 제거 - 더 이상 필요 없음/지워라 라는 의도 |
빈 값, 미정의 명시적 표현 (센티넬/플래그/초기화/의도 표현) |
| 참조 관계 | 이름이 가리키는 객체 연결을 끊음 (= 이름이 사라짐) | 기존 객체와의 연결을 끊음 + 이름은 None을 가리킴 |
| 이후 x 사용 | NameError 발생 (이름 없음) | 정상 사용 가능 (값은 None) |
| 컨테이너 요소 삭제 | 가능 (요소 완전 삭제로 실제 길이도 줄어듦) ex) del lst[i], del d['k'], del arr[a:b] (간결) |
불가능 - 리스트 : 길이 유지, 값만 대입/대체 - 닥셔너리 : 키만 남고 값만 None |
| 에러 유형 | 존재하지 않는 이름/키/인덱스 삭제 시 NameError/KeyError/IndexError 발생 | 대입 자체, ∴ 에러 없음 (우측 연산 예외 제외) |
'Language & Tool > Python' 카테고리의 다른 글
| 🐍리스트와 다른 array 모듈 (0) | 2025.08.25 |
|---|---|
| 🐍컨텍스트 관리자와 자동 자원 관리, with 키워드 (2) | 2025.08.04 |
| 🐍이진 탐색 모듈, bisect (3) | 2025.08.01 |
| 🧵그래프를 표현하는 표현, 인접 리스트와 인접 행렬 (0) | 2025.07.04 |
| 🐍파이썬 함수 인자의 유연성 (0) | 2025.07.01 |