튜플(tuple)은 리스트와 아주 유사합니다. 하지만 튜플의 내용은 변경될 수 없습니다. 어떻게 보면 리스트보다 튜플이 불편합니다.
그렇다면 왜 튜플을 사용하는 것일까요? 어떤 경우에는 리스트가 한번 만들어지면 내용을 변경할 수 없게 하는 것이 도움이 됩니다.
왜냐하면 리스트는 변경될 수 있는 객체이기 때문에 실수로 요소가 추가되거나 삭제, 변경될 수 있기 때문입니다. 또 튜플은 리스트에 비하여 접근 속도가 빠릅니다.
튜플을 생성하려면 소괄호 (...) 안에 요소들을 넣으면 됩니다.
튜플 = (항목1, 항목2, ..., 항목n)
예를 들어 색상을 저장하는 튜플을 생성하면 다음과 같습니다.
colors = ("red", "green", "blue")
print(colors)
<실행 결과>
('red', 'green', 'blue')
물론 정수를 저장하는 튜플도 생성할 수 있습니다.
numbers = (1, 2, 3, 4, 5)
print(numbers)
<실행 결과>
(1, 2, 3, 4, 5)
튜플도 리스트와 마찬가지로 여러 가지 자료형의 값을 섞어서 생성할 수 있습니다.
t = (1, 2, 'hello!')
print(t)
<실행 결과>
(1, 2, 'hello!')
공백 튜플은 단순히 소괄호만 적어주면 됩니다.
t = ()
하나의 값만을 가진 튜플을 생성할 때는 반드시 값 다음에 쉼표를 붙여야 합니다. 쉼표가 없으면 단순한 수식으로 처리됩니다. 즉 (10)은 정수 10이나 마찬가지입니다.
t = (10, )
또 리스트로부터 튜플을 생성할 수도 있습니다.
t = tuple([1, 2, 3, 4, 5])
튜플도 리스트와 마찬가지로 내부에 다른 튜플을 가질 수 있습니다.
t = (1, 2, 'hello!')
u = t, (1, 2, 3, 4, 5)
print(u)
<실행 결과>
((1, 2, 'hello!'), (1, 2, 3, 4, 5))
튜플은 시퀀스의 일종이기 때문에 모든 시퀀스 연산이 적용됩니다. 또 len(), min(), max()와 같은 함수들을 사용할 수 있습니다.
numbers = (1, 2, 3, 4, 5)
print(len(numbers))
<실행 결과>
5
튜플은 변경될 수 없는 객체이므로 튜플의 요소는 변경될 수 없습니다.
t1 = (1, 2, 3, 4, 5)
t1[0] = 100
<실행 결과>
TypeError: 'tuple' object does not support item assignment
하지만 2개의 튜플을 합하여 새로운 튜플을 만들 수는 있습니다. 새로운 튜플을 만드는 것은 허용되지만 한번 만들어진 튜플은 수정할 수 없는 것입니다.
numbers = (1, 2, 3, 4, 5)
colors = ("red", "green", "blue")
t = numbers + colors
print(t)
<실행 결과>
(1, 2, 3, 4, 5, 'red', 'green', 'blue')
튜플은 +와 *와 같은 연산자에 반응합니다. 리스트와 동일하게 +는 접합(concatenation)을 의미하고 *는 반복(repetition)을 의미합니다.
물론 튜플은 변경이 불가능하므로 연산의 결과는 새로운 튜플이 됩니다. 실제로 튜플은 시퀀스가 제공하는 모든 일반 연산을 사용할 수 있습니다.
| 파이썬 수식 | 결과 | 설명 |
| len((1, 2, 3)) | 3 | 튜플의 길이 |
| (1, 2, 3) + (4, 5, 6) | (1, 2, 3, 4, 5, 6) | 접합 |
| ('Hi',) * 4 | ('Hi', 'Hi!', 'Hi!', 'Hi!') | 반복 |
| 3 in (1, 2, 3) | True | 멤버쉽 |
| for x in (1, 2, 3): print x, | 1 2 3 | 반복 |
튜플도 시퀀스의 일종이기 때문에 인덱싱과 슬라이싱은 문자열이나 리스트와 동일하게 동작합니다. 다음과 같은 튜플을 가정합시다.
t = ('apple', 'banana', 'strawberry')
인덱싱과 슬라이싱의 결과는 다음과 같습니다.
튜플은 (...)을 사용하여 감싸는 것이 원칙입니다. 하지만 만약 괄호없이 나열된 객체들은 기본적으로 튜플로 간주됩니다.
t1 = 'physics', 'chemistry', 'c language'
t2 = 1, 2, 3, 4, 5
t3 = "a", "b", "c", "d"
튜플은 다음과 같은 내장 함수를 지원하고 시퀀스가 제공하는 모든 함수는 사용이 가능합니다.
| 함수 | 설명 |
| cmp(t1, t2) | 2개의 튜플을 비교합니다. |
| len(t) | 튜플의 길이를 반환합니다. |
| max(t) | 튜플의 저장된 최댓값을 반환합니다. |
| min(t) | 튜플에 저장된 최솟값을 반환합니다. |
| tuple(seq) | 리스트를 튜플로 변환합니다. |
파이썬은 튜플 대입 연산(tuple assignment)이라는 기능을 가지고 있습니다. 이 기능은 튜플에서 여러 개의 변수로 한번에 값을 대입하는 강력한 기능입니다.
student = ("김봉민", 20, "Computer Science")
(name, age, major) = student
print(name)
print(age)
print(major)
<실행 결과>
김봉민
20
Computer Science
튜플에 값을 저장하는 과정을 튜플 패킹(tuple packing)이라고도 합니다.
반대로 튜플에서 값을 꺼내서 변수에 대입하는 과정을 튜플 언패킹(tuple unpacking) 이라고도 생각할 수 있습니다.
튜플 대입 연산을 가장 효과적으로 사용하는 예가 변수의 값을 교환하는 경우입니다.
일반적으로 프로그래밍 언어에서 변수 x와 변수 y의 값을 교환하려면 다음과 같은 문장을 작성해야 합니다.
temp = x
x = y
y = temp
하지만 튜플에서는 다음과 같이 튜플 대입 연산을 사용하여 한 문장으로 작성하는 것이 가능합니다.
(x, y) = (y, x)
왼쪽은 변수들이 모인 튜플이고 오른쪽은 값들이 모인 튜플이 됩니다. 값은 해당되는 변수에 대입됩니다.
대입되기 전에 오른쪽의 수식들이 먼저 계산되므로 혼동이 발생할 소지는 없습니다. 단 이 경우에 변수의 개수와 값의 개수는 일치하여야 합니다.
(x, y, z) = (1, 2)
<실행 결과>
ValueError: not enough values to unpack (expected 3, got 2)
C++ 과제만 열심히 하던 봉민이는 그 동안 함수가 하나의 값만을 반환할 수 있는 것에 익숙해져 있었습니다.
하지만 파이썬에서는 함수가 튜플을 반환하게 하면 함수가 여러 개의 값을 동시에 반환할 수 있다는 사실을 알고 흥에 겨워 또 점심에 술을 마시러 갔는데요.
이를 활용하여 원의 넓이와 둘레를 동시에 반환하는 함수를 작성하고 테스트해봅시다.
<실행 결과>
원의 반지름을 입력하세요 : 10
원의 넓이는 314.1592653589793이고 원의 둘레는 62.83185307179586입니다.