newclass 2025. 3. 25. 07:03

튜플 (Tuples)

튜플은 리스트와 유사하지만, 한 번 생성하면 변경할 수 없는(immutable) 자료구조입니다. 소괄호 () 안에 쉼표로 구분된 항목들을 나열하여 만듭니다.

튜플 생성하기

# 빈 튜플 생성
empty_tuple = ()
empty_tuple2 = tuple()

# 값이 있는 튜플 생성
numbers = (1, 2, 3, 4, 5)
fruits = ("사과", "바나나", "체리")
mixed = (1, "Hello", 3.14, True)

# 단일 항목 튜플은 쉼표가 필요
single_item = (42,)  # 콤마 필수!
not_tuple = (42)  # 이건 튜플이 아닌 정수
print(type(single_item))  # <class 'tuple'>
print(type(not_tuple))    # <class 'int'>

# 소괄호 없이도 튜플 생성 가능
tuple_without_parentheses = 1, 2, 3, 4, 5
print(type(tuple_without_parentheses))  # <class 'tuple'>

튜플 인덱싱과 슬라이싱

튜플의 인덱싱과 슬라이싱은 리스트와 동일합니다.

fruits = ("사과", "바나나", "체리", "딸기", "오렌지")

# 인덱싱
print(fruits[0])   # 사과
print(fruits[-1])  # 오렌지

# 슬라이싱
print(fruits[1:4])  # ('바나나', '체리', '딸기')
print(fruits[:3])   # ('사과', '바나나', '체리')
print(fruits[2:])   # ('체리', '딸기', '오렌지')
print(fruits[::-1]) # ('오렌지', '딸기', '체리', '바나나', '사과')

튜플의 불변성 (Immutability)

튜플은 생성 후에 항목을 변경, 추가, 삭제할 수 없습니다. 이는 튜플의 핵심 특성입니다.

fruits = ("사과", "바나나", "체리")

# 튜플 항목 변경 시도 (오류 발생)
try:
    fruits[0] = "딸기"  # TypeError: 'tuple' object does not support item assignment
except TypeError as e:
    print(f"오류 발생: {e}")

# 튜플 전체를 다시 할당하는 것은 가능
fruits = ("딸기", "블루베리", "라즈베리")
print(fruits)  # ('딸기', '블루베리', '라즈베리')

튜플 메서드

튜플은 불변성 때문에 리스트보다 메서드가 적습니다.

fruits = ("사과", "바나나", "체리", "사과", "바나나")

# count() - 특정 항목의 개수 반환
apple_count = fruits.count("사과")
print(f"사과의 개수: {apple_count}")  # 사과의 개수: 2

# index() - 특정 항목의 첫 번째 인덱스 반환
banana_index = fruits.index("바나나")
print(f"바나나의 첫 인덱스: {banana_index}")  # 바나나의 첫 인덱스: 1

# 다른 리스트 메서드들(append, remove, sort 등)은 사용할 수 없음

튜플 활용하기

튜플은 여러 값을 묶어서 처리하거나, 함수에서 여러 값을 반환할 때 유용합니다.

# 여러 값 할당 (언패킹)
coordinates = (10, 20)
x, y = coordinates
print(f"x: {x}, y: {y}")  # x: 10, y: 20

# 함수에서 여러 값 반환
def get_person_info():
    name = "홍길동"
    age = 30
    city = "서울"
    return name, age, city  # 암시적 튜플 반환

# 반환값 언패킹
person_name, person_age, person_city = get_person_info()
print(f"이름: {person_name}, 나이: {person_age}, 도시: {person_city}")

# 일부만 언패킹하고 나머지는 모으기 (Python 3.x)
numbers = (1, 2, 3, 4, 5)
first, second, *rest = numbers
print(first)  # 1
print(second)  # 2
print(rest)   # [3, 4, 5] (나머지는 리스트로 묶임)

first, *middle, last = numbers
print(first)   # 1
print(middle)  # [2, 3, 4]
print(last)    # 5

튜플과 리스트 간 변환

# 리스트를 튜플로 변환
fruits_list = ["사과", "바나나", "체리"]
fruits_tuple = tuple(fruits_list)
print(fruits_tuple)  # ('사과', '바나나', '체리')

# 튜플을 리스트로 변환
numbers_tuple = (1, 2, 3, 4, 5)
numbers_list = list(numbers_tuple)
print(numbers_list)  # [1, 2, 3, 4, 5]

리스트와 튜플의 비교

공통점

  1. 순서가 있는 시퀀스 타입
  2. 인덱싱과 슬라이싱으로 접근 가능
  3. 다양한 데이터 타입 저장 가능
  4. len(), max(), min() 등의 내장 함수 사용 가능
  5. in 연산자로 항목 존재 여부 확인 가능

차이점

특성 리스트 튜플
문법 대괄호 [] 소괄호 ()
변경 가능성 변경 가능(Mutable) 변경 불가능(Immutable)
메모리 사용 더 많은 메모리 사용 더 적은 메모리 사용
성능 동적 크기 조정 가능 고정 크기로 더 빠름
사용 케이스 데이터 수정이 필요한 경우 상수 데이터, 딕셔너리 키, 함수 반환값
보안 변경 가능하여 덜 안전 변경 불가능하여 더 안전
메서드 다양한 메서드 제공 제한된 메서드 (count, index)

언제 리스트를 사용해야 할까?

  1. 데이터를 자주 추가, 삭제, 수정해야 할 때
  2. 정렬, 역순, 셔플 등의 조작이 필요할 때
  3. 컬렉션의 크기가 동적으로 변할 때
  4. 동적인 데이터를 다룰 때 (예: 사용자 입력, 계산 결과)

언제 튜플을 사용해야 할까?

  1. 데이터가 변경되지 않아야 할 때
  2. 딕셔너리의 키로 사용할 때 (딕셔너리 키는 불변 객체여야 함)
  3. 함수에서 여러 값을 반환할 때
  4. 보호하고 싶은 데이터가 있을 때
  5. 약간의 성능 향상이 필요할 때