티스토리 뷰

파이썬에서의 unpacking의 개념과 예제에 대해 알아보고자 한다.

<목차>
 - 언패킹(unpacking)
    1) 기본 unpacking
    2) *를 통한 unpacking
        2-1) 일반적인 형태에서의 * 사용
        2-2) 함수에서의 * 사용
    3) **를 통한 unpacking
        3-1) 일반적인 형태에서의 ** 사용
        3-2) 함수에서의 ** 사용          

언패킹(unpacking)

패킹과 반대되는 개념으로, 한 변수의 데이터를 각각의 변수로 반환하는 것 -> 묶인 걸 푼다!

 

1) 기본 unpacking

 

직관적인 unpakcing으로, 오른쪽에 위치한 iterable 데이터 (예. list, tuple, string, dictionary 등) 의 각 원소들이 변수에 순서대로 할당되는 작업이다.

# list unpacking
num1, num2, num3 =  [1, 2, 3]
print(num1, num2, num3) # 1 2 3

# tuple unpacking
name, student_num = ('홍길동', 240515)
print(name, student_num) # 홍길동 240515

# string unpacking
s1, s2, s3 = 'ABC'
print(s1, s2, s3) # A B C

# dictionary unpacking
d1, d2, d3 = {'k1':1, 'k2':2, 'k3':3}.items()
print(d1, d2, d3) # ('k1', 1) ('k2', 2) ('k3', 3)

# set unpakcing
s1, s2, s3, s4, s5 = {'a', 'b', 'c', 'd', 'e'}
print(s1, s2, s3, s4, s5) # d c b e a

 

여기서, set은 순서가 없는 데이터 타입이므로,

unpakcing하면 순서대로가 아닌 뒤죽박죽으로 값이 할당되기 때문에 unpacking의 의미가 없어 사용하지는 않는다.

 

2) *을 통한 unpacking

 

2-1) 일반적인 형태에서의 * 사용

 

iterable 데이터들을 분해하는 역할을 한다.

당연히, unpakcing을 통해 각 리스트에 있는 값들을 분해한 후, 새로운 list, tuple를 만들 수도 있다.

# list unpacking
l1 = [1,2,3,4,5]
print(*l1) # 1 2 3 4 5

# string unpacking
s1 = 'XYZ'
print(*s1) # [1, 2, 3, 4, 5, 'X', 'Y', 'Z']

# tuple unpacking
t1 = (1,2,3)
print(*t1) # 1 2 3

# 새로운 list 생성 가능 
print([*l1,*s1,*t1]) # [1, 2, 3, 4, 5, 'X', 'Y', 'Z', 1, 2, 3]

 

이때, list, tuple로 싸지않고 그냥 *로 풀어헤치기만 한다면, 다음과 같이 syntaxError가 난다.

l1 = [1,2,3,4,5]
l2 = *l1

 

2-2) 함수에서의 * 사용

 

iterable 형태의 데이터 앞에 *를 붙여, 각 원소를 unpacking하여 함수의 인수값으로 넣어주면 된다.

l = [1, 2, 3] # 리스트 정의

def func(num1,num2, num3):
    print(num1) # 1
    print(num2) # 2
    print(num3) # 3

func(*l)

 

 

3) **을 통한 unpacking

 

3-1) 일반적인 형태에서의 ** 사용

 

**는 dictionary를 unpacking하는 목적으로 사용한다.

d1 = {'k1':1, 'k2':2}
d2 = {'k3':3, 'k4':4}
d3 = {'k4':5, 'k6':6}

d = {*d1, *d2, *d3}
print(d) # {'k2', 'k3', 'k4', 'k6', 'k1'}

 

dictionary를 unpacking 한 후 set의 형태로 값을 묶었다. (set 형태로 묶어 순서가 무작위이고, 중복되는 key 사라진다)

*로 unpakcing을 하니 key 값만 가져왔다.

 

key와 value를 한번에 가져오기 위해서 사용하는 것이 **이다.

d1 = {'k1':1, 'k2':2}
d2 = {'k3':3, 'k4':4}
d3 = {'k4':5, 'k6':6}

d = {**d1, **d2, **d3}
print(d) # {'k1': 1, 'k2': 2, 'k3': 3, 'k4': 5, 'k6': 6}

 

+) 참고

dictionary의 특성에는 key 값이 중복되면 안된다. 

따라서, 결과값을 보면, key 값 중 k4가 중복이여서, d에는 'k4':4가 아닌 k4:5가 있다.

구체적으로 말하면, 순서상 늦게 정의된 k4:5가 이전 값을 overrride한 것이다. 

# override example1
d1 = {'k1':1, 'k2':2}
d2 = {'k1':3, 'k4':4, **d1}

print(d2) # {'k1': 1, 'k4': 4, 'k2': 2}

 

k1:3이 먼저 정의되었고, 그다음 k1:1이 정의 되었다.

즉, 뒤에 온 k1:1이 먼저 정의되었더 k1:3을 override하였다.

# override example2
d1 = {'k1':1, 'k3':2}
d2 = { **d1, 'k1':3, 'k4':4}

print(d2) # {'k1': 3, 'k3': 2, 'k4': 4}

 

마찬가지로, k1:1이 먼저 정의되었고, 뒤에 온 k1:3가 override하였다.

 

3-2) 함수에서의 ** 사용

 

함수에서의 **사용은

앞선 일반적인 형태와 비슷하다!

 

대신 *args와 마찬가지로 관용적인 표현인  **kwargs를 사용한다. 

**kwargs: keyword 매개변수로, 전달되는 인수를 딕셔너리 형태의 변수에 저장하는 방법이다.

 

아래와 같이 딕셔너리 형태의 인자를 넘겨줄 때 사용하면 된다.

def func(**kwargs):
    print(kwargs) # {'a': 1, 'b': 2, 'c': 3}

func(a=1, b=2, c=3)

 

 

*args, **kwargs에 대해서 더 알고 싶다면 [바로가기]

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/06   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함