[Python] 튜플의 패킹과 언패킹, 네임드 튜플

2 분 소요

패킹과 언패킹

튜플로 값을 묶는 행위를 ‘튜플 패킹’, 튜플로 묶여 있는 값들을 풀어내는 행위를 ‘튜플 언패킹’ 이라고 한다.

>>> tri_one = (12,15) # 튜플 패킹
>>> tir_two = 23, 12  # 튜플 패킹 시 소괄호 없어도 됨.

>>> bt, ht = tri_one  # 튜플 언패킹
>>> print(bt, ht)
12 15
>>> nums = (1,2,3,4,5)
>>> n1, n2, *others = nums # 둘 이상의 값을 리스트로 묶을 때 * 사용
>>> n1
1
>>> n2
2
>>> others  # 튜플이 아닌 리스트로 묶인다.
[3,4,5]
>>> nums = (1,2,3,4,5)
>>> n1, *others, n2 = nums 
>>> n1
1
>>> n2
5
>>> others 
[2,3,4]

언패킹 과정에서 뒤쪽에 있는 값들만 리스트로 묶을 수 있는 게 아니다. 위 코드와 같이 중간에 있는 값들을 묶을 수도 있다.

언패킹은 튜플뿐문 아니라 리스트도 가능하다.

>>> def ret_nums():
        return 1,2,3,4,5   # 튜플의 소괄호가 생략된 형태. 패킹되어 반환됨.

>>> nums = ret_nums()
>>> nums
(1,2,3,4,5)

>>> n, *others = ret_nums()
>>> n
1
>>> others  # 리스트로 묶임
[2,3,4,5]

>>> def show_nums(n1, n2, *other): # 매개변수 앞에 *이 오면 나머지 값들을 튜플로 묶어서 변수에 저장한다는 의미.
        print(n1, n2, other, sep=', ')

>>> show_nums(1,2,3,4)
1, 2, (3, 4)
>>> def sum(*nums):
        s = 0
        for i in nums:
            s += i
        return s

>>> sum(1,2,3)
6
>>> sum(1,2,3,4)
10
>>> def show_man(name, age, height):
        print(name, age, height, sep=', ')

>>> p = ('Lee', 23, 170)  # p = ['Lee', 23, 170]  리스트도 가능.
>>> show_man(*p)  # p 에 담긴 값을 풀어서 각 매개변수에 전달
Lee, 23, 170
>>> p = 'Hong', (32,178), '010-1111-1111', 'korea'
>>> na, (ag, he), ph, ad = p
>>> print(na, he)
Hong 178
>>> na, (_, he), _, _ = p
>>> print(na, he)
Hong 178

튜플안에 튜플이 있는 경우 동일한 형태로 변수를 선언해 언패킹을 해야 한다. 만약 불필요한 정보까지 변수에 담는 것이 번거롭다면 불필요한 정보가 있는 위치에 _을 대신 넣는다. _도 변수이다. 이것은 일종의 관례이다.

>>> ps = [('Lee',172), ('Jung',182), ('Yoon', 179)] # (['Lee',172], ['Jung',182], ['Yoon', 179]) 도 가능
>>> for n, h in ps:
        print(n,h,sep=', ')

Lee, 172
Jung, 182
Yoon, 179



네임드 튜플

>>> from collections import namedtuple  # collections모듈의 nametuple 호출
>>> Tri = namedtupe('Triangle', ['bottom', 'height']) # 네임드 튜플 클래스 만듬
>>> t = Tri(3,7)
>>> print(t[0], t[1]) # 일반 튜플과 동일한 방법으로 접근 가능
3 7
>>> print(t.bottom, t.height) # 일반 튜플과 달리 이름으로도 접근이 가능
3 7

namedtuple 함수가 호출되면 Tri에는 Triangle 클래스의 정보가 담기게 되는데, 이 변수를 이용해서 네임드 튜플 객체(Triangle 클래스의 객체)를 생성해야 한다. 즉 클래스의 이름인 Triangle은 객체 생성에 사용되지 않는다. 이 이름은 오류가 발생했을 때 오류의 원인을 찾는 데 도움이 된다.

네임드 튜플 역시 일반 튜플과 마찬가지로 저장된 값을 수정하지 못한다.

>>> from collections import namedtuple  # collections모듈의 nametuple 호출
>>> Tri = namedtupe('Tri', 'bottom height') # 네임드 튜플 클래스 만듬

위 코드와 같이 클래스의 이름과 변수의 이름이 달라야 하는 것은 아니다. 둘의 이름을 동일하게 해서 네임드 튜플 클래스를 만들어도 된다. 이렇게 만들면 변수와 클래스의 이름이 같게 되어 불필요한 혼동을 줄일 수 있다. 이는 실제로 프로그래머들이 많이 사용하는 방법이다. 또한 네임드 튜플의 이름을 지정할 때 리스트에 담아서 전달하지 않고 위 코드처럼 하나의 문자열에 담아서 전달해도 된다.

>>> from collections import namedtuple  # collections모듈의 nametuple 호출
>>> Tri = namedtupe('Triangle', ['bottom', 'height']) # 네임드 튜플 클래스 만듬
>>> t = Tri(3,7)
>>> a,b = t # 언패킹
>>> print(a,b)
3 7

>>> def show(n1,n2):
        print(n1, n2)

>>> show(*t) # 값의 전달 과정에서 언패킹
3 7

언패킹은 일반 튜플과 동일하다.