목차
Python을 사용하는 개발자라면 누구나 한 번쯤은 List vs Tuple 사이에서 고민해본 적이 있을 것입니다. 두 자료구조는 모두 순서가 있는 컬렉션 타입으로, 문법상 큰 차이가 없어 보이지만 속도, 메모리, 사용 목적 측면에서 분명한 차이를 보입니다.
이번 글에서는 Python의 List vs Tuple 의 차이점, 장단점, 사용 예시, 코드 비교를 통해 어떤 상황에서 어떤 구조를 선택해야 하는지 상세히 살펴보겠습니다.
List란?
기본 개념
Python에서 가장 널리 쓰이는 가변형(변경 가능한) 시퀀스 자료형입니다. 다양한 자료를 저장하고, 자유롭게 수정하거나 삭제할 수 있어 동적 데이터 처리에 매우 유용합니다.
문법
colors = ['red', 'blue', 'black']
- 대괄호
[]
사용 - 요소 수정 가능
- 다양한 메서드 지원
주요 메서드
append()
: 요소 추가insert()
: 특정 위치에 요소 삽입remove()
: 요소 삭제pop()
: 마지막 요소 제거len()
: 리스트 길이 반환sort()
/reverse()
등 정렬
장점
- 유연성: 요소 추가, 삭제, 수정이 가능
- 다양한 기능 지원:
append()
,extend()
,pop()
등 풍부한 메서드 제공 - 동적 크기 조절: 상황에 따라 리스트 크기가 자동 조절됨
단점
- 메모리 사용량: 가변 구조로 인해 메모리를 더 많이 사용
- 성능 저하: 불변 구조인
tuple
보다 약간 느릴 수 있음
Tuple이란?
기본 개념
**Tuple(튜플)**은 리스트와 비슷하지만 불변형(immutable) 자료구조입니다. 즉, 생성 후에는 내용을 바꿀 수 없습니다. 변경이 불필요한 데이터를 다룰 때 안정성과 성능에서 이점을 제공합니다.
문법
colors = ('red', 'blue', 'black')
- 소괄호
()
사용 - 요소 변경 불가
- 메서드 수 제한
장점
- 불변성: 실수로 데이터가 변경되는 걸 막을 수 있어 안정성 ↑
- 성능 우수: 리스트보다 메모리 사용량과 속도 측면에서 효율적
- 해싱 가능: 딕셔너리 키나 set 요소로 사용 가능
단점
- 수정 불가: 요소를 추가하거나 삭제할 수 없음
- 메서드 제한: list에 비해 제공되는 메서드가 매우 적음
코드 예시: List → Tuple → List
colors = ['red', 'blue', 'black']
# 요소 추가
colors.append('white')
print(colors)
# 요소 삽입
colors.insert(1, 'yellow')
print(colors)
# 요소 수정
colors[2] = 'gray'
print(colors)
# 요소 삭제
colors.remove('yellow')
print(colors)
# 슬라이싱
print(colors[1:3]) # ['gray', 'black']
# 리스트 → 튜플 변환
colors = tuple(colors)
print(type(colors)) # <class 'tuple'>
print(colors[1:3]) # ('gray', 'black')
# 튜플 → 리스트 변환
colors_list = list(colors)
print(colors_list)
List vs Tuple 비교
항목 | List (리스트) | Tuple (튜플) |
---|---|---|
변경 가능성 | ✅ 가능 (mutable) | ❌ 불가 (immutable) |
정의 방식 | 대괄호 [] | 소괄호 () |
메서드 수 | 많음 (append , pop ) | 적음 (count , index ) |
메모리 효율 | 낮음 | 높음 |
속도 | 느림 | 빠름 |
해시 가능성 | ❌ 불가 | ✅ 가능 (딕셔너리 키로 사용 가능) |
실무 활용 팁
언제 List를 쓰면 좋을까?
- 데이터가 변경될 가능성이 있을 때
- 사용자의 입력, 실시간 수집 데이터 등 동적으로 변하는 값
언제 Tuple이 적합할까?
- 데이터가 고정되어 있고 변경이 필요 없을 때
- 딕셔너리 키, 함수 리턴 값 집합, 좌표(x, y) 등
실무에서의 경험
개발 초반엔 List vs Tuple 을 ‘변수 모음’ 정도로만 생각했습니다. 그래서 대부분 리스트로 통일해서 사용하고, 사용이 끝난 후에도 메모리 상에 계속 두는 경우가 많았습니다.
하지만 프로젝트 규모가 커지고, 데이터가 많아지면서 메모리 관리와 속도의 중요성을 실감하게 됐습니다. 이후로는 가급적 필요한 시점에 불필요한 리스트는 삭제하고, 변경이 필요 없는 데이터는 튜플로 선언하는 습관을 들이게 됐습니다.
# 불필요한 리스트 삭제
del colors_list
이런 작은 습관 하나가 코드의 안정성과 성능 최적화에 기여합니다.
자주 발생하는 에러와 해결방안
1. IndexError: list index out of range
설명: 리스트 또는 튜플에서 존재하지 않는 인덱스를 접근할 때 발생
my_list = [1, 2, 3]
print(my_list[5]) # 에러 발생
해결: 인덱스가 리스트 길이보다 작은지 확인하거나 len()
함수로 안전하게 처리
if len(my_list) > 5:
print(my_list[5])
2. TypeError: 'tuple' object does not support item assignment
설명: 튜플은 불변(immutable)이기 때문에 값을 변경할 수 없음
my_tuple = (1, 2, 3)
my_tuple[0] = 10 # 에러 발생
해결: 값을 바꾸고 싶다면 튜플을 리스트로 변환해서 수정 후 다시 튜플로
temp = list(my_tuple)
temp[0] = 10
my_tuple = tuple(temp)
3. ValueError: list.remove(x): x not in list
설명: 리스트에서 존재하지 않는 값을 제거하려고 할 때
my_list = [1, 2, 3]
my_list.remove(5) # 에러 발생
해결: in
키워드로 존재 여부 확인 후 제거
if 5 in my_list:
my_list.remove(5)
4. TypeError: list indices must be integers or slices, not str
설명: 리스트는 문자열 인덱싱이 안 됨
my_list = [10, 20, 30]
print(my_list["1"]) # 에러 발생
해결: 문자열 인덱스를 정수로 변환
print(my_list[int("1")])
5. AttributeError: 'tuple' object has no attribute 'append'
설명: 튜플에는 .append()
같은 메서드 없음
my_tuple = (1, 2, 3)
my_tuple.append(4) # 에러 발생
해결: 리스트로 변환해서 사용
temp = list(my_tuple)
temp.append(4)
my_tuple = tuple(temp)
List vs Tuple 마무리
이 글을 작성하는 이유는 가장 기본적이지만 매우 강력한 자료구조이기 때문입니다. 두 구조 모두 순서를 유지하고 여러 자료형을 포함할 수 있지만, 가변성의 유무에 따라 사용 목적과 상황이 크게 달라집니다.
단순히 외워서 사용하는 것이 아니라, 어떤 데이터에 적합한지 고민하고 선택하는 습관이 더 중요합니다. 코드의 효율성과 유지보수성을 높이는 출발점이 바로 여기에 있습니다.