3. 자료구조

3.3. 튜플

3.3.1. 튜플 생성

  • 튜플(tuple)
    • 여러 개의 값을 저장할 수 있는 컬렉션 자료형(collection data type)
    • 순서가 존재하는 시퀀스 자료형(sequence data type)
    • 한 번 생성된 이후에는 수정할 수 없는 불변형(immutable) 객체
    • 정수형, 부동소수점형, 문자열형, bool형, 리스트, 튜플, 딕셔너리 등 다양한 자료형을 저장할 수 있는 컨테이너형 객체
    • 리스트와 구조 및 사용 방법이 거의 동일하지만, 수정이 불가능하다는 차이점이 있음


  • 튜플 생성
    • 리터럴 방식(tuple literal)
      • ()를 사용하여 튜플을 직접 정의하는 방법
      • () 안에 원소(element)를 ,로 구분하여 나열함
      • ()을 생략할 수도 있지만, 원소가 하나인 경우에는 (값,)처럼 반드시 ,를 포함해야 함
    • 생성자 방식(tuple constructor)
      • tuple() 함수를 사용하여 튜플을 생성하는 방법
      • 다른 iterable 객체(리스트, 튜플, 세트, 딕셔너리, 문자열 등)를 인수로 받아 튜플을 생성할 때 유용함
# 튜플 생성1
tpl = (1, 2, 3, 4, 5)
print(tpl)
(1, 2, 3, 4, 5)
# 튜플 생성2
tpl = 1, 2, 3, 4, 5
print(tpl)
(1, 2, 3, 4, 5)
# 튜플 생성3 : 원소가 하나인 경우에는 반드시 ,를 포함해야 함
tpl = (1,)
print(tpl)
(1,)
# 튜플 생성4 : 튜플은 다양한 자료형을 저장할 수 있음
tpl = (1, 3.14, "Hello", True, [11, 12, 13], (21, 22))
print(tpl)
(1, 3.14, 'Hello', True, [11, 12, 13], (21, 22))
# 튜플 생성5 : iterable 객체 사용
tpl = tuple("Hello")
print(tpl)
('H', 'e', 'l', 'l', 'o')
# 튜플 생성6 : iterable 객체 사용
tpl = tuple([1, 2, 3])
print(tpl)
(1, 2, 3)


3.3.2. 튜플 연산

  • 리스트 연산과 문법이 동일함
  • 튜플 연결 연산자 + : 두 튜플을 연결해서 새로운 튜플 생성
  • 튜플 반복 연산자 * : 튜플을 숫자만큼 반복하여 새로운 튜플 생성 - (예) 튜플*숫자
  • 튜플 전개 연산자 * : 튜플의 개별 원소를 분리하여 다른 튜플 전개 - (예) (*튜플)
# 튜플 연결
tpl1 = 1, 2, 3
tpl2 = 11, 12, 13
print(tpl1 + tpl2)
(1, 2, 3, 11, 12, 13)
# 튜플 반복
print(tpl1 * 3)
(1, 2, 3, 1, 2, 3, 1, 2, 3)
# 튜플 전개
tpl = 1, 2, 3, 4, 5
print((tpl, tpl))
print((*tpl, *tpl))
((1, 2, 3, 4, 5), (1, 2, 3, 4, 5))
(1, 2, 3, 4, 5, 1, 2, 3, 4, 5)


3.3.3. 튜플 패킹과 언패킹

3.3.3.1. 패킹과 언패킹 개념

  • 패킹(packing) : 여러 개의 데이터를 한 변수에 묶어 할당하는 것
  • 언패킹(unpacking) : 한 변수에 묶인 데이터를 개별적인 변수들에 할당하는 것
# 튜플 패킹
tpl = 1, 2, 3
print(tpl)
(1, 2, 3)
# 튜플 언패킹
tpl = 1, 2, 3
x, y, z = tpl
print(x)
print(y)
print(z)
1
2
3
# 튜플 패킹과 언패킹 : 임시변수 없이 두 변수의 값을 쉽게 교환할 수 있음
a = 7
b = 11
a, b = b, a
print(a)
print(b)
11
7
# 언패킹 시 변수 개수 불일치 오류
#a, b = 1, 2, 3
#x, y, z = 4, 5
# 언패킹 시 *을 이용한 가변 개수 처리
# *변수는 여러 개의 값을 저장해야 하므로, 가변적인 리스트로 처리됨
*x, y, z = 5, 6, 7, 8
print(x)
print(y)
print(z)
[5, 6]
7
8


3.3.3.2. 함수의 인수에서 패킹과 언패킹

  • 가변 인수를 사용하면 전달된 인수들은 튜플로 패킹됨
  • *를 사용하여 튜플을 언패킹하여 함수에 전달함
# 가변 인수와 패킹, 언패킹
def print_args(*args):
    print("Packed arguments:", args)                        # 전달된 값이 튜플로 패킹됨

print_args(1, 2, 3, 4)

tpl = 11, 12, 13
print_args(tpl)                                             # 튜플 자체를 인수로 전달
print_args(*tpl)                                            # 튜플을 언패킹하여 함수에 전달
Packed arguments: (1, 2, 3, 4)
Packed arguments: ((11, 12, 13),)
Packed arguments: (11, 12, 13)
# 키워드 인수와 언패킹
def sum_numbers(a, b, c, d):
    return a + b + c + d

tpl = 1, 2, 3, 4

print(sum_numbers(tpl[0], tpl[1], tpl[2], tpl[3]))          # 개별 원소를 인수로 전달
print(sum_numbers(*tpl))                                    # 튜플을 언패킹하여 함수에 전달
10
10


3.3.3.3. 함수의 반환값에서 패킹과 언패킹

  • 함수에서 여러 개의 값을 반환하면 자동으로 튜플로 패킹됨
  • 함수가 반환한 튜플을 언패킹하여 개별 변수에 할당할 수 있음
# 반환값과 패킹, 언패킹
def get_student_info():
    return "Alice", 20, "Statistics"                        # 튜플로 자동 패킹됨

# 패킹된 값 출력
info = get_student_info()
print(info)

# 언패킹하여 개별 변수에 할당
name, age, major = get_student_info()
print(name)
print(age)
print(major)
('Alice', 20, 'Statistics')
Alice
20
Statistics


3.3.4. 튜플 인덱싱와 슬라이싱

  • 리스트와 문법이 동일함
  • 인덱싱(indexing) : [index]를 사용하여 튜플의 특정 위치에 있는 원소에 접근함
  • 슬라이싱(slicing) : [(start index):(stop index)]를 사용하여 튜플의 일부 원소를 추출함
    • 리스트와 달리 불변형 객체이므로 슬라이싱을 이용하여 기존 튜플의 일부를 삭제하거나, 새로운 원소를 추가 및 변경할 수 없음
# 튜플 인덱싱1
tpl = 1, 2, 3, 4, 5
print(tpl[0])
1
# 튜플 인덱싱2
tpl = 1, 2, 3, 4, 5
print(tpl[-1])
5
# 튜플 슬라이싱1
tpl = 1, 2, 3, 4, 5
print(tpl[0:2])
(1, 2)
# 튜플 슬라이싱2
tpl = 1, 2, 3, 4, 5
print(tpl[:2])
print(tpl[2:])
print(tpl[::2])
(1, 2)
(3, 4, 5)
(1, 3, 5)
# 튜플은 불변형 객체이므로 인덱스를 이용한 수정이 불가능함
#tpl = 1, 2, 3, 4, 5
#tpl[2] = 3
#print(tpl)


3.3.5. 튜플 메소드

함수 설명
count() 튜플 내부에 특정 값이 몇 번 나타나는지 개수를 반환
index() 튜플 내부에 특정 값의 첫 번째 인덱스를 반환하며, 없으면 오류 발생
in 연산자 튜플 내부에 특정 값이 있다면 True, 없다면 False를 반환
len() 튜플 원소의 개수(튜플 길이) 반환
sum() 튜플 원소의 합계 반환
max() 튜플 원소 중 최대값 반환
min() 튜플 원소 중 최소값 반환
# 특정 값 개수
tpl = 1, 2, 3, 1, 4, 5, 1, 6, 7
print(tpl.count(1))
print(tpl.count(9))
3
0
# 특정 값의 첫 번쩨 인덱스
tpl = 1, 2, 3, 1, 4, 5, 1, 6, 7
print(tpl.index(1))
#print(tpl.index(9))
0
# 특정값 찾기
tpl = 1, 2, 3, 4, 5
print(3 in tpl)
print(6 in tpl)
True
False
tpl = 1, 2, 3, 4, 5
print(len(tpl))
print(sum(tpl))
print(max(tpl))
print(min(tpl))
5
15
5
1