수학과의 좌충우돌 프로그래밍

[python] 언패킹, *args, **kwargs 본문

프로그래밍 언어/Python

[python] 언패킹, *args, **kwargs

ssung.k 2019. 10. 28. 21:28

언패킹이란

간단히 두 수를 더하는 함수를 만들어보겠습니다.

def mysum(a,b):
    result = a+b
    return result

print(mysum(3,5)) # 8

mysum 이라는 함수는 두 수를 인자를 받은 후 두 수를 더해 return 해주는 함수입니다.

 

다음 함수를 이용하여 아래와 같이 리스트 안에 있는 두 수의 값을 더해줄 수도 있습니다.

def mysum(a,b):
    result = a+b
    return result

mylist = [3,5]

print(mysum(mylist[0],mylist[1])) # 8

 

우리는 mylist 안에 값이 두 개 있는 걸 알고 있어서 mysum 함수에 리스트를 매개변수를 넣어주면 편하겠지만 이 함수는 해당 리스트 안에 값이 몇 개 존재하는지 알지 못합니다. 그래서 리스트를 매개변수로 넘겨주기 위해서는 언패킹 을 해야합니다. 언패킹이란 포장을 푼다는 뜻으로, 리스트를 풀어헤쳐 그 안의 값들이 함수의 매개변수로 대응될 수 있도록 해줍니다. 언패킹을 하는 방법은 매개변수로 넘겨줄 때 * 을 붙여줍니다.

def mysum(a,b):
    result = a+b
    return result

mylist = [3,5]

print(mysum(*mylist)) # 8

 

함수의 매개변수를 유동적으로

위의 mysum 는 아쉽게도 두 수의 덧셈 밖에 하지 못합니다. 만약 이 함수가 매개변수를 가변적으로 받을 수 있더라면 어떤 리스트가 들어오더라도 리스트 안 원소들의 합을 구할 수 있을 겁니다.

물론 리스트의 모든 원소의 합을 구하는 sum 이라는 함수가 있지만 지금은 이 부분이 포인트가 아니니 넘어가겠습니다.

다행히도 함수의 매개변수를 유동적으로 받을 수 있습니다. 이를 가변인수함수 라고 합니다. 가변인수함수는 매개변수 앞에 * 을 붙여서 만들어줍니다.

def mysum(*args):
    result = 0
    for num in args:
        result = result + num
    return result

mylist = [3,5,7]

print(mysum(*mylist)) # 15

이 때 함수의 매개변수 argsarguments 의 줄임말로서 다른 키워드를 사용해도 무방합니다. 또한 이 값은 들어오는 값을 투플로 변환하기 때문에 다음과 같이 for 문을 통한 순회가 가능합니다.

가변인수는 고정인수와도 함께 사용이 가능합니다. 이 때 주의해야 할 점은 가변인수가 고정인수보다 뒤 쪽에 위치해야한다는 점입니다.

 

키워드 인수

지금까지는 데이터가 전부 동등한 위치에 있는 데이터였습니다. 데이터간의 순서가 바뀌어도 아무런 문제가 되지 않았죠. 다음의 경우에는 어떨까요?

def subject(math, english, korean):
    print('수학 성적: ', math)
    print('영어 성적: ', english)
    print('국어 성적: ', korean)

subject(90,85,70)
#수학 성적:  90
#영어 성적:  85
#국어 성적:  70

값의 입력 순서에 따라서 성적이 뒤바뀔 수 있으니 자리를 확실히 지켜줘야합니다. 그러기 위해서는 함수의 매개변수 순서를 항상 확인해야하는 번거로움이 생기죠. 이를 위해 키워드 인수 가 있습니다. 함수를 호출할 때 매개변수의 이름에 대응시켜 준다면 순서에 상관없이 원하는 결과를 얻을 수 있습니다.

subject(english=85,korean=70,math=90)
#수학 성적:  90
#영어 성적:  85
#국어 성적:  70

 

키워드 인수와 딕셔너리를 활용한 언패킹

위에서 봤던 언패킹과 같은 흐름으로 방금 보았던 키워드 인수와 딕셔너리에도 적용할 수 있습니다.

def subject(math, english, korean):
    print('수학 성적: ', math)
    print('영어 성적: ', english)
    print('국어 성적: ', korean)


myscore = {'english': 85, 'korean': 70, 'math': 90}
subject(**myscore)

이 때 함수의 매개변수 이름과 딕셔너리의 키값은 일치해야합니다.

 

혹시나 실수로 * 를 한 개 빼먹지는 않으셨나요? 그렇다면 아래와 같이 의외의 결과를 확인할 수 있습니다.

def subject(math, english, korean):
    print('수학 성적: ', math)
    print('영어 성적: ', english)
    print('국어 성적: ', korean)


myscore = {'english': 85, 'korean': 70, 'math': 90}
subject(*myscore)
#수학 성적:  english
#영어 성적:  korean
#국어 성적:  math

함수의 매개변수로 딕셔너리의 밸류가 아닌 키가 들어갔습니다. 즉 * 를 한 번만 사용한다면 키가, 두 번 사용하면 밸류가 들어가는 것이죠.

 

키워드 인수를 사용하여 함수의 매개변수를 유동적으로

함수의 매개변수 앞에 ** 를 붙여준다면 유동적으로 딕셔너리를 받을 수 있습니다. 이럴 경우 kwargs 는 딕셔너리가 되고 아래와 같이 순회할 수 있습니다.

def subject(**kwargs):
    for key,value in kwargs.items():
        print(key+' 성적: ', value)


myscore = {'english': 85, 'korean': 70, 'math': 90}
subject(**myscore)

 

Comments