파이썬 튜플 자료구조 이해하기

튜플(tuple)이란 용어는 값의 유한한 순서의 배열을 설명하기 위해 사용 되는 수학적인 용어이다. 튜플은 요소가 순서대로 표시되기 때문에 순서가 지정되어 있다. 즉, (1, 2, 3)
과 같은 튜플이 있을 때, 첫 번째 요소는 1이고 두 번째 요소는 2, 세 번째 요소는 3인 것이다. 파이썬에서는 수학적 개념인 튜플의 이름과 작성법을 빌려 사용한다.
튜플 생성하기
튜플 생성하는 방법 중 두 가지는 다음과 같다.
- 튜플 리터럴
- 내장
tuple()
함수
튜플 리터럴(Tuple Literal)
문자열 리터럴이 일부 텍스트를 따옴표로 묶어서 명시적으로 만든 문자열인 것처럼, 튜플 리터럴은 괄호로 묶고 쉼표로 구분된 값의 리스트 형식으로 명시적으로 작성된 튜플이다.
튜플 리터럴의 예시는 다음과 같다.
>>> my_first_tuple = (1, 2, 3)
정수 1, 2, 3을 담고 있는 튜플이 생성되고 my_first_tuple
이라는 변수에 할당된다. 다음과 같이 type()
함수를 사용해 변수의 타입을 체크할 수 있다.
>>> type(my_first_tuple)
<class 'tuple'>
문자의 배열을 가진 문자열과는 다르게, 튜플은 어떤 종류의 값이라도 담을 수 있다. 예를 들어, (1, 2.0, "three")
와 같이 다른 종류의 값을 가지고 있는 튜플 또한 유효하다.
빈 튜플 생성하기
파이썬에는 아무 값도 담고 있지 않은 특별한 튜플이 존재한다. 이 튜플은 빈 튜플(empty tuple)이라고 불리며 다음과 같이 아무 값 없이 빈 괄호로 생성할 수 있다.
>>> empty_tuple = ()
빈 튜플이 쓸모 없다고 생각이 들 수 있지만, 사실 상당히 실용적이다. 예를 들어, 짝수와 홀수인 정수를 모두 포함하는 튜플을 만들어야 한다고 가정해보자. 그런 정수는 존재하지 않지만, 빈 튜플을 생성함으로써 위와 같은 요청의 튜플을 제공할 수 있게 된다.
하나의 요소를 가진 튜플 생성하기
단 하나의 요소를 가진 튜플을 생성하려면 어떡해야할까? 다음 예제를 확인해보자.
>>> x = (1)
>>> type(x)
<class 'int'>
위 예제에서 보이는 것과 같이, 쉼표를 포함하지 않고 하나의 값을 괄호로 감싸주면, 파이썬에서는 그 값을 튜플로 해석하지 않고, 괄호 안의 값의 타입으로 해석한다. 그렇기 때문에 (1)
의 타입이 정수인 것이다.
단일 값 1을 담고 있는 튜플을 생성하려면 다음과 같이 쉼표를 포함해야 한다.
>>> x = (1,)
>>> type(x)
<class 'tuple'>
내장 tuple() 함수
파이썬 내장 함수인 tuple()
함수를 사용해서 다른 타입의 시퀀스 자료형을 튜플로 생성할 수 있다.
>>> tuple("Python")
('P', 'y', 't', 'h', 'o', 'n')
tuple()
함수는 오직 하나의 매개변수만을 허용한다. 만약 값 들을 줄지어 전달한다면 파이썬은 TypeError
를 일으킨다.
>>> tuple(1, 2, 3)
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
tuple(1, 2, 3)
TypeError: tuple expected at most 1 arguments, got 3
만약 tuple()
함수에 인수로 전달된 값이 목록으로 해석될 수 없을 때 또한 TypeError
가 발생한다.
>>> tuple(1)
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
tuple(1)
TypeError: 'int' object is not iterable
에러 메시지 안에 이터러블(iterable)이란 단어는 단일 정수 값 1이 반복될(iterated) 수 없다는 것이다. 즉, 정수 자료형에 하나씩 접근할 다수의 값을 포함하지 않고 있다는 것이다.
tuple()
함수에 매개변수는 선택적이다. 매개변수를 비어두면 빈 튜플을 생성한다.
>>> tuple()
()
튜플과 문자열의 유사점
튜플과 문자열은 많은 공통점을 가진다. 둘 다 유한한 길이를 가진 시퀀스 자료형이며, 인덱싱과 슬라이싱을 지원하고, 불변객체이며, 반복문 안에서 반복될 수 있다.
튜플과 문자열 사이의 가장 큰 차이점은, 튜플의 요소들은 어떤 종류의 값이라도 될 수 있다는 것이다. 반면에 문자열은 문자밖에 담아내지 못한다. 튜플과 문자열의 유사점을 더 자세히 알아보도록 하자.
튜플은 길이를 가진다
튜플과 문자열 둘 다 길이(length)를 가진다. 문자열의 길이는 문자열 안 문자의 수이지만, 튜플의 길이는 튜플이 담고 있는 요소의 수다.
>>> numbers = (1, 2, 3)
>>> len(numbers)
3
튜플은 인덱싱과 슬라이싱을 지원한다
튜플은 문자열과 마찬가지로 인덱싱과 슬라이싱을 지원한다. 사용 방법을 동일하며 예제는 다음과 같다.
인덱싱
# 문자열
>>> name = "Jacob"
>>> name[1]
'a'
# 튜플
>>> values = (1, 3, 5, 7, 9)
>>> values[2]
5
슬라이싱
# 문자열
>>> name = "Jacob"
>>> name[2:4]
"co"
# 튜플
>>> values = (1, 3, 5, 7, 9)
>>> values[2:4]
(5, 7)
튜플은 불변객체이다
문자열과 마찬가지로 튜플은 불변객체이다. 즉, 튜플이 생성되고 나서 튜플 안에 요소의 값을 변경할 수 없다는 것이다. 만약 튜플의 값을 변경하려고 시도한다면, 파이썬은 TypeError
를 일으킨다.
>>> values[0] = 2
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
values[0] = 2
TypeError: 'tuple' object does not support item assignment
튜플은 반복이 가능하다
튜플도 문자열처럼 반복문 안에서 반복이 가능하다.
>>> vowels = ("a", "e", "i", "o", "u")
>>> for vowel in vowels:
... print(vowel.upper())
...
A
E
I
O
U
튜플 패킹과 언패킹
튜플을 생성하는 또 다른 방법이 존재하는데 바로 패킹(packing)이라고 불리는 방법이다. 값 들의 목록을 쉼표로 나누고 괄호 없이 사용할 수 있다.
>>> coordinates = 4.21, 9.29
>>> type(coordinates)
<class 'tuple'>
위 예제를 보면, 두 가지의 값이 coordinates
라는 하나의 변수에 할당된 것처럼 보인다. 어떤 의미에서는 맞는 말이지만, 그러나 결과는 두 가지 값 모두 하나의 튜플에 패킹되었다.
튜플에 값을 패킹할 수 있으면, 반대로 언패킹도 당연히 가능해야 할 것이다.
>>> x, y = coordinates
>>> x
4.21
>>> y
9.29
coordinates
라는 단일 튜플에 담긴 값들이 두 개의 다른 변수 x
와 y
에 언패킹되었다. 튜플 패킹과 언패킹을 합쳐 사용함으로써, 다수의 변수 할당을 한줄로 작성할 수 있다.
>>> name, age, occupation = "David", 34, "programmer"
>>> name
'David'
>>> age
34
>>> occupation
'programmer'
한 줄에 여러 개의 변수에 할당함으로 프로그램을 짧게 작성할 수는 있지만, 한 줄에 너무 많은 값을 할당하는 것은 자제해야 한다.
이런식으로 두 개나 세 개 이상의 변수에 할당하는 것은 어떤 값이 어떤 변수 이름에 할당 되었는지 구분하기 어려워진다.
한 가지 조심해야 할 부분은, 튜플 형태의 값의 수가 변수의 이름의 수와 동일하지 않으면 파이썬은 ValueError
를 일으킨다.
>>> a, b, c, d = 1, 2, 3
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
a, b, c, d = 1, 2, 3
ValueError: not enough values to unpack (expected 4, got 3)
반대 상황도 마찬가지로 에러를 발생한다.
>>> a, b, c = 1, 2, 3, 4
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
a, b, c = 1, 2, 3, 4
ValueError: too many values to unpack (expected 3)
튜플 활용하기
튜플 값 존재 여부 확인
in
키워드를 사용하면 특정 값이 튜플에 존재하는지 확인할 수 있다. 특정 값이 존재하면 True
, 없으면 False
를 반환한다.
>>> vowels = ("a", "e", "i", "o", "u")
>>> "o" in vowels
True
>>> "x" in vowels
False
함수로부터 다수의 값 반환하기
튜플이 흔히 사용되는 방법 중 하나가 바로 단일 함수에서 여러 개의 값을 반환하는 것이다. 다음 예제처럼, 리턴문에서 튜플을 사용함으써 여러 값을 반환할 수 있다.
>>> def adder_subtractor(num1, num2):
... return (num1 + num2, num1 - num2)
...
>>> adder_subtractor(3, 2)
(5, 1)