Python 기초

튜플

튜플(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')

 

인덱싱과 슬라이싱의 결과는 다음과 같습니다.

  • L[1] : 'banana' (인덱스는 0부터 시작합니다.)
  • L[-2] : 'banana' (음수 인덱스는 오른쪽부터 왼쪽으로 진행됩니다.)
  • L[1:] : ['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입니다.