본문 바로가기

Python

3-2. 튜플(Tuple)과 불변성

파이썬 튜플(Tuple)과 불변성 타이틀

안녕하세요! 지난 시간에는 파이썬의 가장 유용하고 유연한 자료구조인 리스트(List)에 대해 자세히 알아보았습니다. 리스트는 순서가 있고, 다양한 자료형을 저장할 수 있으며, 무엇보다 내용을 자유롭게 변경(추가, 삭제, 수정)할 수 있는 특징이 있었죠.

이번 시간에는 리스트와 매우 비슷하게 여러 데이터를 순서대로 담지만, 결정적인 차이를 가진 또 다른 자료구조인 **튜플(Tuple)**에 대해 알아보겠습니다. 튜플의 가장 중요한 특징은 바로 **불변성(Immutability)**입니다.

"불변성"이 무엇인지, 그리고 튜플은 어떤 상황에 사용되는지 함께 살펴볼까요?


Part 1: 튜플(Tuple)이란 무엇인가?

파이썬의 튜플은 다음과 같은 특징을 가집니다.

  • 순서가 있다: 리스트와 마찬가지로 데이터를 저장한 순서가 유지됩니다. 따라서 인덱스를 사용하여 특정 위치의 데이터에 접근할 수 있습니다.
  • 다양한 자료형 저장 가능: 하나의 튜플 안에 정수, 실수, 문자열, 심지어 다른 리스트나 튜플까지! 어떤 자료형의 데이터든 함께 저장할 수 있습니다.
  • 변경 불가능하다 (Immutable): 이것이 리스트와 튜플의 가장 큰 차이점입니다. 한 번 튜플을 만들면 그 안에 있는 요소를 추가, 삭제, 변경할 수 없습니다.
  • 중복 허용: 같은 값을 여러 번 저장할 수 있습니다.

1. 튜플 만들기

튜플은 괄호(()) 안에 쉼표(,)로 구분하여 요소들을 나열하는 방식으로 만듭니다. 괄호를 생략하고 쉼표만으로도 튜플을 만들 수 있습니다.

예시:

Python
 
# 파일 이름: tuple_creation.py

# 다양한 자료형을 포함하는 튜플
my_tuple = (1, 2, "hello", 3.14, True)
fruits_tuple = ("사과", "바나나", "체리", "사과") # 중복 허용

# 괄호 없이 쉼표로만 튜플 생성 (권장되지 않으나 가능)
coordinates = 10, 20, 30

# 요소가 하나인 튜플 만들기 (쉼표가 중요!)
single_element_tuple = (5,) # 괄호 안에 요소 하나만 있고 쉼표가 있어야 튜플로 인식
not_a_tuple = (5)           # 괄호만 있으면 그냥 5 (정수)로 인식

# 빈 튜플
empty_tuple = ()

print(f"my_tuple: {my_tuple}, 타입: {type(my_tuple)}")
print(f"fruits_tuple: {fruits_tuple}, 타입: {type(fruits_tuple)}")
print(f"coordinates: {coordinates}, 타입: {type(coordinates)}")
print(f"single_element_tuple: {single_element_tuple}, 타입: {type(single_element_tuple)}")
print(f"not_a_tuple: {not_a_tuple}, 타입: {type(not_a_tuple)}") # int로 출력됨
print(f"empty_tuple: {empty_tuple}, 타입: {type(empty_tuple)}")

 
# 파일 이름: tuple_creation.py

# 다양한 자료형을 포함하는 튜플
my_tuple = (1, 2, "hello", 3.14, True)
fruits_tuple = ("사과", "바나나", "체리", "사과") # 중복 허용

# 괄호 없이 쉼표로만 튜플 생성 (권장되지 않으나 가능)
coordinates = 10, 20, 30

# 요소가 하나인 튜플 만들기 (쉼표가 중요!)
single_element_tuple = (5,) # 괄호 안에 요소 하나만 있고 쉼표가 있어야 튜플로 인식
not_a_tuple = (5)           # 괄호만 있으면 그냥 5 (정수)로 인식

# 빈 튜플
empty_tuple = ()

print(f"my_tuple: {my_tuple}, 타입: {type(my_tuple)}")
print(f"fruits_tuple: {fruits_tuple}, 타입: {type(fruits_tuple)}")
print(f"coordinates: {coordinates}, 타입: {type(coordinates)}")
print(f"single_element_tuple: {single_element_tuple}, 타입: {type(single_element_tuple)}")
print(f"not_a_tuple: {not_a_tuple}, 타입: {type(not_a_tuple)}")
print(f"empty_tuple: {empty_tuple}, 타입: {type(empty_tuple)}")

[VS Code 터미널 출력]

파이썬 튜플 생성 및 자료형 확인 예시

Part 2: 튜플 요소 접근하기 - 인덱싱(Indexing) 및 슬라이싱(Slicing)

튜플도 리스트와 마찬가지로 순서가 있는 자료구조이기 때문에, 인덱싱과 슬라이싱을 통해 요소에 접근할 수 있습니다.

  • 인덱싱: 대괄호 [] 안에 인덱스 번호를 넣어 특정 위치의 요소를 가져옵니다. (0부터 시작, 음수 인덱스 가능)
  • 슬라이싱: 콜론 :을 사용하여 튜플의 특정 부분(범위)을 잘라내어 새로운 튜플을 만듭니다.

1. 인덱싱으로 요소 접근

예시:

Python
 
# 파일 이름: tuple_indexing.py

coordinates = (10, 20, 30, 40, 50)

# 양수 인덱스
print(f"첫 번째 요소 (인덱스 0): {coordinates[0]}")
print(f"세 번째 요소 (인덱스 2): {coordinates[2]}")

# 음수 인덱스
print(f"마지막 요소 (인덱스 -1): {coordinates[-1]}")
print(f"뒤에서 세 번째 요소 (인덱스 -3): {coordinates[-3]}")

 
# 파일 이름: tuple_indexing.py

coordinates = (10, 20, 30, 40, 50)

# 양수 인덱스
print(f"첫 번째 요소 (인덱스 0): {coordinates[0]}")
print(f"세 번째 요소 (인덱스 2): {coordinates[2]}")

# 음수 인덱스
print(f"마지막 요소 (인덱스 -1): {coordinates[-1]}")
print(f"뒤에서 세 번째 요소 (인덱스 -3): {coordinates[-3]}")

[VS Code 터미널 출력]

파이썬 튜플 인덱싱 예시

 

2. 슬라이싱으로 부분 튜플 가져오기

예시:

Python
 
# 파일 이름: tuple_slicing.py

numbers_tuple = (10, 20, 30, 40, 50, 60, 70)

# 인덱스 1부터 4까지 (인덱스 4 미포함)
slice1 = numbers_tuple[1:5]
print(f"numbers_tuple[1:5]: {slice1}") # (20, 30, 40, 50)

# 처음부터 인덱스 3까지 (인덱스 3 미포함)
slice2 = numbers_tuple[:3]
print(f"numbers_tuple[:3]: {slice2}") # (10, 20, 30)

# 인덱스 4부터 끝까지
slice3 = numbers_tuple[4:]
print(f"numbers_tuple[4:]: {slice3}") # (50, 60, 70)

# 전체 튜플 복사
slice4 = numbers_tuple[:]
print(f"numbers_tuple[:]: {slice4}") # (10, 20, 30, 40, 50, 60, 70)

 
# 파일 이름: tuple_slicing.py

numbers_tuple = (10, 20, 30, 40, 50, 60, 70)

# 인덱스 1부터 4까지 (인덱스 4 미포함)
slice1 = numbers_tuple[1:5]
print(f"numbers_tuple[1:5]: {slice1}")

# 처음부터 인덱스 3까지 (인덱스 3 미포함)
slice2 = numbers_tuple[:3]
print(f"numbers_tuple[:3]: {slice2}")

# 인덱스 4부터 끝까지
slice3 = numbers_tuple[4:]
print(f"numbers_tuple[4:]: {slice3}")

# 전체 튜플 복사
slice4 = numbers_tuple[:]
print(f"numbers_tuple[:]: {slice4}")

[VS Code 터미널 출력]

파이썬 튜플 슬라이싱 예시

 


Part 3: 튜플의 불변성 (Immutability) - 가장 중요한 특징!

튜플은 한 번 생성되면 그 요소를 변경(수정, 추가, 삭제)할 수 없습니다. 이 특징을 **불변성(Immutability)**이라고 합니다.

1. 불변성으로 인한 오류 확인

예시:

Python
 
# 파일 이름: tuple_immutability.py

my_tuple = (10, 20, 30)
print(f"원본 튜플: {my_tuple}")

# 튜플 요소 변경 시도 (오류 발생!)
# my_tuple[0] = 5 # TypeError: 'tuple' object does not support item assignment

# 튜플에 요소 추가 시도 (오류 발생!)
# my_tuple.append(40) # AttributeError: 'tuple' object has no attribute 'append'

# 튜플 요소 삭제 시도 (오류 발생!)
# del my_tuple[0] # TypeError: 'tuple' object doesn't support item deletion

print("튜플은 한 번 생성되면 요소를 변경할 수 없습니다.")

 
# 파일 이름: tuple_immutability.py

my_tuple = (10, 20, 30)
print(f"원본 튜플: {my_tuple}")

# 튜플 요소 변경 시도 (오류 발생!)
# my_tuple[0] = 5 # TypeError: 'tuple' object does not support item assignment

# 튜플에 요소 추가 시도 (오류 발생!)
# my_tuple.append(40) # AttributeError: 'tuple' object has no attribute 'append'

# 튜플 요소 삭제 시도 (오류 발생!)
# del my_tuple[0] # TypeError: 'tuple' object doesn't support item deletion

print("튜플은 한 번 생성되면 요소를 변경할 수 없습니다.")

[VS Code 터미널 출력 (오류 발생 시)]

파이썬 튜플 불변성으로 인한 오류 예시

(위 오류는 my_tuple[0] = 5 주석을 해제하고 실행했을 때 발생하는 예시입니다.)

 

2. 튜플 안에 '변경 가능한' 객체가 있을 경우 (주의!)

튜플 자체가 불변이라는 것은 튜플의 '요소'를 변경할 수 없다는 의미입니다. 하지만 튜플 안에 리스트처럼 '변경 가능한(mutable)' 객체가 들어있다면, 그 변경 가능한 객체 내부의 내용은 변경할 수 있습니다.

예시:

Python
 
# 파일 이름: tuple_mutable_element_caution.py

# 튜플 안에 리스트가 요소로 들어있는 경우
my_data = (1, [2, 3], 4)
print(f"원본 튜플: {my_data}")

# 튜플의 두 번째 요소(리스트)에 접근하여 리스트 내부의 요소 변경
my_data[1][0] = 99
print(f"리스트 내부 변경 후: {my_data}") # (1, [99, 3], 4)

# 튜플의 요소를 완전히 교체하는 것은 불가능
# my_data[1] = [5, 6] # TypeError 발생

 
# 파일 이름: tuple_mutable_element_caution.py

# 튜플 안에 리스트가 요소로 들어있는 경우
my_data = (1, [2, 3], 4)
print(f"원본 튜플: {my_data}")

# 튜플의 두 번째 요소(리스트)에 접근하여 리스트 내부의 요소 변경
my_data[1][0] = 99
print(f"리스트 내부 변경 후: {my_data}")

# 튜플의 요소를 완전히 교체하는 것은 불가능
# my_data[1] = [5, 6] # TypeError 발생

[VS Code 터미널 출력]

튜플 안에 변경 가능한 객체가 있을 때의 동작

 


Part 4: 튜플은 언제 사용해야 할까? (리스트와의 비교)

튜플과 리스트는 유사해 보이지만, 불변성이라는 중요한 차이 때문에 사용되는 목적이 다릅니다.

특징리스트(List)튜플(Tuple)
변경 가능성 변경 가능 (Mutable) 변경 불가능 (Immutable)
괄호 대괄호 [] 괄호 () 또는 생략
용도 - 요소의 추가/삭제/변경이 잦은 데이터- 동적으로 크기가 변하는 컬렉션 - 변하면 안 되는 고정된 데이터
- 함수의 인자로 데이터를 전달할 때 (의도치 않은 변경 방지)
- 딕셔너리의 키로 사용 (리스트는 안 됨)
- 프로그램 실행 속도 면에서 리스트보다 약간 빠름
예시 [1, 2, 3], ['apple', 'banana'] (10, 20, 30), (3.14, '파이')
Sheets로 내보내기

튜플을 사용하는 주요 상황:

  • 좌표 값: (x, y) 또는 (경도, 위도)처럼 여러 개의 고정된 값을 하나의 묶음으로 표현할 때.
  • 색상 값: (빨강, 초록, 파랑) RGB 값처럼 고정된 순서와 의미를 가진 값들.
  • 함수의 반환 값: 함수에서 여러 값을 묶어서 반환할 때.
  • 딕셔너리의 키: 변경될 수 없는 값만이 딕셔너리의 키가 될 수 있는데, 튜플은 불변이라 키로 사용 가능합니다. (딕셔너리는 다음 포스팅에서 배울 거예요!)

마무리하며

이번 시간에는 파이썬의 중요한 자료구조 중 하나인 **튜플(Tuple)**에 대해 알아보았습니다. 튜플은 리스트와 유사하게 여러 데이터를 순서대로 담지만, **한 번 생성되면 내용을 변경할 수 없는 불변성(Immutable)**이라는 핵심 특징을 가집니다.

이 불변성 덕분에 튜플은 '변하면 안 되는 고정된 데이터'를 표현하거나, 데이터의 안정성을 확보해야 할 때 유용하게 사용됩니다. 리스트와 튜플의 차이점을 명확히 이해하고 적절한 상황에 사용하는 것이 중요합니다.

다음 포스팅에서는 '키(Key)'와 '값(Value)' 쌍으로 데이터를 저장하는 강력한 자료구조인 **딕셔너리(Dictionary)**에 대해 자세히 알아보겠습니다.


궁금한 점이 있다면 언제든지 질문해주세요! 다음 포스팅에서 만나요!

반응형