python 함수

0

CS 지식

목록 보기
6/7

함수에 관한 기본적인 내용을 정리하겠습니다.

인수의 종류

positional argument

함수는 일반적으로 인자를 입력받고 그 인자를 함수의 정의에 대응해서 결과를 출력하는 과정을 거칩니다.

이 때 함수 인자는 적힌 순서대로 함수로 입력이 됩니다(이 때 입력은 튜플에 형태로 입력됩니다.). 위 예에서 "kevin" , "name"은 ("kevin" , "name")로 입력이 되어서 retrun 값에 대응이 됩니다.

이 인수는 자리에 따라 해당 위치로 대응되기 때문에 위치인수 (positional argument)라 합니다.
만일 여기서 "name", "kevin"로 입력한다면 출력 결과는 반대로 출력이 됩니다. 위치에 따라 인수를 인식하기 때문입니다.

keyword argument

위에 위치인수는 위치값에 따라 대응되는 결과가 다르다고 했습니다. 항상 순서를 지키고 입력을 할 수도 없고 함수를 호출할 때 값만을 입력하는 것은 어떤 인수에 대응되는 지 이해하기에 직관적이지 못합니다.

이 때 필요한 것이 keyword argument입니다.
keyword argument는 순서를 고려하지 않고 해당 인수의 자리를 찾아서 대응되게 합니다.

'

위 이미지에서 (파란색, 초록색) 순서로 함수는 정의되어있지만 호출을 할 때는 (초록색, 파란색) 키워드를 입력하여 호출을 했습니다. 다만 키워드를 입력하여 출력을 했습니다. 그 결과는 원래 의도대로 출력이 된 것을 알 수 있습니다!
이렇듯 키워드 인수를 사용하면 입력된 인수의 위치와 관계없이 원하는 결과를 출력할 수 있습니다.
(그 이유는 딕셔너리인 키:값으로 입력되기 때문에)

default value parameter

default value parameter는 함수 요청시 파라미터에 값이 들어가지 않았을 기본으로 대응하는 변수를 의미합니다

def i_can_do_this (name = "캡틴아메리카", time = "all day") :

	return f"{name} can do this {time} 

다음과 같은 함수가 있다고 가정하겠습니다. 이 함수를 호출할 때는 2개의 변수가 필요하고 이 변수는 각각 nametime 입니다. 만약 함수를 호출할 때 한가지만 입력한다면 어떻게 될까요?

만약 함수가 아래와 같이 정의 되어있다면 )

def i_can_do_this (name, time ) :

	return f"{name} can do this {time} 

i_can_do_this("kevin")만 입력하게된다면

parameter time이 누락이 되었다고 나옵니다.

만약 여기에 default value parameter를 적용해주면 에러가 나오지 않고 해당 default value로 나타납니다.
(이 때 default value parameter는 함수 정의시 해당 파라미터 = "디폴트 값"으로 정의해주면 됩니다. )

파라미터에 아무 값을 입력하지 않고 해당 함수를 호출했지만 에러가 아닌 디폴트 값으로 출력 결과가 나왔습니다.

variable length arguments

해당 인수가 정해진대로 들어오면 좋지만 항상 정해진 숫자로 들어오는 것은 아닙니다. 자동차의 옵션을 값으로 받을 때 옵션은 선루프, 네비게이터 부터 휠 제작사, 엉뜨 등 여러 옵션이 있습니다. 그리고 모든 고객들이 이 옵션을 필수로 선택하는 것도 아니고요. 이렇기 때문에 미리 함수를 정의할 떄 각 인수를 다 설정하기 보다는 신축성있게 인수를 구성하는 것이 중요합니다.

이때 필요한 것이 가변인수입니다.

표시 방법은 함수 정의시 def function(*args)로 표현을 해주는 방식입니다.
앞에 를 붙여주는 건 언패킹을 위해서입니다. 이전에 이야기한 것처럼 function의 입력값들은 튜플로 받고 그 튜플을 를 통해서 언패킹을 해주는 과정입니다.

그러면 이전에는 필요하지 않았던 언패킹의 과정이 왜 필요해졌는지 궁금하실 겁니다.
그 이유는 이전에는 각각의 인수의 개수의 맞게 입력이 되었지만 입력되는 값과 함수정의에서의 인수 개수가 다르기 때문입니다.

다음과 같은 함수에서 인수는 *args를 포함하여 3개입니다. 이와는 달리 함수를 입력할 때는 총 4개의 인수가 입력이 됐습니다. 이 때 입력값은 각각의 위치인수와 가변인수를 고려해서 ("정우성", 20, ("01012341234","seoul"))로 입력이 됩니다. 튜플 안에 튜플이 또 있는 모양이죠 따라서 *로 언패킹을 하고 위치인수에 대응되지 않는 나머지 인수들은 언패킹되어 차근차근 들어갑니다.

("정우성", 20, ("01012341234","seoul"))
("정우성", 20, *("01012341234","seoul"))
("정우성", 20, "01012341234","seoul")

가변인수 사용시 주의점

가변인수는 항상 정의할 때 마지막으로 넣어줘야 에러가 나오지 않습니다. 그 이유는 컴퓨터는 위치인수에 대응하지 않는 것들은 전부 가변인수에 들어가는 튜플로 인식하기 때문에 가변인수 뒤에 또 하나의 인수를 원한다면 이에 대응되는 인수는 입력값을 받을 수 없는 것입니다.


다음과 같은 예에서는 name = "정우성"에 대응되지만 ( "01012341234", "seoul", 20)까지 전부 args로 인식이 되어서 age에 해당하는 입력값이 없게 됩니다.


이 사실은 위에 에러에서 한 번 더 확인할 수 있습니다.

variable length keyword arguments(가변 키워드 인수)

가변키워드인수는 이름에서 알 수 있다시피 가변인수 + 키워드인수의 기능을 합니다.

가변인수는 뒤에 값이 얼마나 오든지 하나의 튜플로 묶여서 언패킹이 된다고 말씀드렸습니다. 키워드인수딕셔너리로 입력된다고도 설명드렸구요. 그래서 가변 키워드 인수는 딕셔너리를 언패킹하는 과정을 거칩니다.

가변 키워드인수를 이용한 문제를 풀며 개념을 확인해보겠습니다.

what_is_my_full_name 함수는 주어진 parameterfirst_namelast_name 이라는 parameter를 조합하여 full namereturn 해주어야 합니다.
예를 들어, first_name이 "우성" 이고 last_name 이 "정" 이면 "정 우성" 라고 return 하면 됩니다.
Last namefirst name 사이에 space(빈칸)이 들어가 있어야 합니다.
만일 last_name이 없거나 first_name이 없으면 둘 중하나만 return 하면 됩니다.
예를 들어, last_name이 없으면 "우성" 이라고 이름만 return 하면 됩니다.

이 문제의 핵심은 어떤 변수가 키워드인수로 주어지고 혹은 아예 안주어질 수도 있다는 것입니다.

즉 키워드인수 + 가변인수의 성격을 가지는 키워드 가변인수(**kwarg)를 사용해야 하죠.

우선 키워드인수 데이터를 다루는 방법을 적겠습니다.
키워드 인수는 딕셔너리로 들어가기 때문에 이 부분의 값을 받으려면 딕셔너리의 키 값 가져오는
dict.items()를 활용합니다.

먼저 문제를 해결하면서 제가 가장 해멨던 부분을 알려드리겠습니다. 제가 계속 실수 했던 코드는 다음과 같습니다.

함수 안에서 for문을 돌렸는데 결과 값이 하나만 나올때 해결방법!

근데 출력을 해보면 한 개의 값 밖에 나오지 않습니다. 이 이유는 for문으로 첫번째 값을 받고 return을 만나서 2번째 값까지 받지 않기 때문에 첫째까지만 나오게 됩니다. (파이썬 indent는 신이고 무적이야~)

함수 입장에서는 for문으로 첫번째 값을 받았는데 return을 하라고 하니 현재 값을 리턴하고 break를 걸어서 for문 + 함수가 끝이 나게 되는 거죠.


문제 이어서 해결

반면 제가 원하는 것은 key값이 "first_name"일 때 값과 "last_name"일 때 값입니다. 이를 위해서는 dict["key"] 값으로 출력을 해야 합니다.

문제는 이렇게 값을 받게 되면 for 문에 마지막으로 들어간 2번째 값만이 메모리에 남게 됩니다 .


이 문제를 해결하는 방법은 빈 딕셔너리를 만드는 방법이 있습니다. for 문에 값들을 딕셔너리에 넣게 되면 사라지지 않고 계속 확인할 수 있는 것이죠.

다만 여전히 값만 받는 게 아니라 키와 값 둘 다를 받게 됩니다. 이를 해결하려면 코드를 다음과 같이 수정을 해줘야 합니다.

구체적인 키값의 해당하는 값을 각각 가져오면 딕셔너리 형태가 아닌 원하는 값을 가져올 수 있습니다.

profile
기록을 통해 한 걸음씩 성장ing!

0개의 댓글