05. 함수(Function) 다루기

안녕하세요 이전 포스팅 애서는 Pyhton 데이터들을 다룰 때 유용한 반복문(for, while)과 조건문(if)에 대해서 얘기를 나눠봤는데요. 이번 포스팅에서는 프로그래밍의 꽃(?)이라 할 수 있는 함수 정의에 대해서 얘기해보려고 합니다.

  • 함수(Function) 정의하기
  • Parameter vs Arguments 짚고 넘어가기
  • lambda 다뤄보기

함수(Function) 정의하기

왜(Why)?

먼저 바로 함수 작성하는 방법을 설명드리기전에 왜(why) 함수를 사용하는지부터 얘기해보죠.

  1. 간결한 코드 작성이 용이해진다.
  2. 한 번 작성한 함수는 재사용이 가능하다.
  3. 가독성, 코드 유지관리가 쉬워진다.
  4. 등…

사실 함수를 사용하면 정말 많은 장점이 존재합니다. 그리고 그 장점 끝에는 “코드 작성자 & 팀원과 공유할 때 커뮤니케이션이 원활해진다.” 로 이어집니다. 그럼 이제 본격적으로 함수를 어떻게 작성하는지부터 얘기를 해보겠습니다.

함수 작성법

파이썬에서는 함수를 정의할 때 다음과 같이 정의합니다.

함수 정의 예시
1
2
3
def add(x, y):
result = x+y
return result

여기서 defdefine(정의하다) 의 앞 글자를 딴 것인데요. 그리고 add는 우리가 정의한 함수의 이름 이 됩니다. 그리고 조건문, 반복문과 같이 함수명 뒤에 콜론(:) 그리고 indent를 해준 뒤 이 함수가 수행할 코드를 입력 한 후, 그 결과를 return(반환) 하는 구조입니다.

즉, 정의한 함수 add두 변수(x,y)를 받아서 더한 값을 반환하는 함수 입니다.

Parameter vs Arguments 짚고 넘어가기

Parameter와 Arguments의 차이에 대해서 잠깐 짚고 넘어가겠습니다.

Parameter(매개변수)와 Arguments(인수)의 구분
1
2
3
4
5
6
def add(x, y):
result = x+y
return result

z = add(3,4)
print(z)
7

간단합니다.

  • Parameter는 함수를 정의할 때 입력으로 전달받는 변수를 의미하고,
  • Arguments는 함수를 사용(호출)할 때 입력되는 값을 의미합니다.

즉, 위 예시코드에서 x,y는 Parameter(매개변수) 이고, 3, 4는 Arguments(인수) 가 되는 것이죠.

Lambda 다뤄보기

우리는 Lambda 를 통해 이름이 없는 함수를 만들 수 있습니다. 이름이 없다(?) 이해가 안가실 텐데요. 예시 보겠습니다.

Lambda 예시
1
2
3
4
5
6
7
8
9
10
def add(x, y):
result = x+y
return result

print(add(3,4))

no_name = lambda x, y: x + y
print(no_name(3,4))

print((lambda x, y: x + y)(3,4))
7
7
7

위 코드에서 lambda를 사용해서 add()와 같은 기능을 수행하는 함수를 정의했습니다. 7번째 줄 에서는 이름을 정하지 않았다는 것을 보여드리기 위해 임의로 no_name이라는 변수에 담아서 표현을 한 것입니다. 강조드리고 싶은 것은 10번째 줄 인데요. lambda를 사용하는 것에는 크게 2가지 장점이 있습니다.

  1. 간결한 코드를 작성할 수 있다.
  2. 메모리 절약

여기서 저는 장점 1번을 좀 더 강조드리고 싶은데요. 글로 설명할게 아니라 코드로 바로 보겠습니다.

lambda 활용 예시 - sorted()

sorted 험수는 list 타입의 객체에 내장되어 있는 함수 입니다.

sorted() 함수 Description
1
2
3
4
sorted(iterable, key=None, reverse=False)
- iterable : A sequence (string, tuple, list) or collection (set, dictionary, frozen set) or any other iterator.
- reverse (Optional) : If True, the sorted list is reversed (or sorted in descending order). Defaults to False if not provided.
- key (Optional) : A function that serves as a key for the sort comparison. Defaults to

sorted 함수 파라미터에 대한 설명을 보면, 파라미터 reversekey 는 옵션으로 우리가 정의할 수 있는데요. 만약, 우리가 다루는 list 타입의 데이터를 문자열의 길이가 긴 것부터 정렬해야 한다면? 두가지 방식을 비교해 보겠습니다.

def 로 함수를 정의했을 때
1
2
3
4
5
6
7
list_sample = ['a', 'bb', 'ccc', 'dddd', 'eeeee']

def check_str_length(x):
return len(x)

new_list_sample = sorted(list_sample, key=check_str_length, reverse=True)
print(new_list_sample)
['eeeee', 'dddd', 'ccc', 'bb', 'a']
lambda 로 함수를 정의했을 때
1
2
3
4
list_sample = ['a', 'bb', 'ccc', 'dddd', 'eeeee']

new_list_sample = sorted(list_sample, key=lambda x: len(x), reverse=True)
print(new_list_sample)
['eeeee', 'dddd', 'ccc', 'bb', 'a']

어떤가요? lambda를 사용했을 때 코드가 더 간결해진게 느껴지시나요? 다음 예시 보겠습니다.

lambda 활용 예시 - map()

map 함수는 sorted와 마찬가지로 iterable한 데이터를 받아서 각 요소마다 특정 동작을 수행할 수 있도록 해주는 함수입니다.

map() 함수 Description
1
2
3
map(function, iterable, ...)
- function : a function that perform some action to each element of an iterable
- iterable : an iterable like sets, lists, tuples, etc

만약, 위 예시에서 사용했던 list_sample의 요소들을 각 길이값으로 바꿔야하면? 두가지 방식을 비교해 보겠습니다.

def 로 함수를 정의했을 때
1
2
3
4
5
6
7
8
list_sample = ['a', 'bb', 'ccc', 'dddd', 'eeeee']

def check_str_length(x):
return len(x)

new_list_sample = map(check_str_length, list_sample)
print(new_list_sample)
print(list(new_list_sample))
<map object at 0x7fc0d1304590>
[1, 2, 3, 4, 5]
lambda 로 함수를 정의했을 때
1
2
3
4
5
list_sample = ['a', 'bb', 'ccc', 'dddd', 'eeeee']

new_list_sample = map(lambda x: len(x), list_sample)
print(new_list_sample)
print(list(new_list_sample))
<map object at 0x7fc0d12e28d0>
[1, 2, 3, 4, 5]

자 여기서 map() 함수가 반환한 것은 object of map class 즉, iterator 이기 떄문에 list()로 감싸주어 형변환을 해준뒤 출력한 것입니다.

lambda 활용 예시 - filter()

filter 함수의 경우 map함수와 가장 자주 비교되서 설명되는 함수입니다. 특정 조건으로 걸러진 요소들을 새롭게 객체로 만들어 반환 하는 함수입니다.

filter() 함수 Description
1
2
3
filter(function, iterable
- function : a function
- iterable : an iterable like sets, lists, tuples, etc

위 예시들을 그대로 사용하겠습니다. 여기서는 길이가 3이상인 것들만 다시 반환하고 싶다면? 두가지 방식을 비교해 보겠습니다.

def 로 함수를 정의했을 때
1
2
3
4
5
6
7
8
9
10
11
list_sample = ['a', 'bb', 'ccc', 'dddd', 'eeeee']

def filter_three_len(x):
if len(x) >= 3:
return x
else:
pass

new_list_sample = filter(filter_three_len, list_sample)
print(new_list_sample)
print(list(new_list_sample))
<filter object at 0x7fc0d09f80d0>
['ccc', 'dddd', 'eeeee']
lambda 로 함수를 정의했을 때
1
2
3
4
5
list_sample = ['a', 'bb', 'ccc', 'dddd', 'eeeee']

new_list_sample = filter(lambda x: len(x) >= 3, list_sample)
print(new_list_sample)
print(list(new_list_sample))
<filter object at 0x7fc0d13c33d0>
['ccc', 'dddd', 'eeeee']

결론

이번 포스팅에서는 함수 를 주제로 얘기를 해봤는데요. 먼저 어떻게 함수를 정의하는지 에 대해서 얘기를 해봤습니다. 그리고 Parameter, Arguments 차이에 대해서 잠깐 짚고 넘어갔구요. 그리고 일회성 함수로 사용하는 Lambda 작성하는 방법에 대해서 설명드렸습니다. 추가로 lambda 를 활용하는데 있어서 sorted(), map(), filter() 함수까지 알아봤습니다. 사실 위 함수들 같은 경우 for문 을 사용해서 똑같은 결과를 얻는 것 까지 다룰까 했지만, 이 부분은 각자 개인적으로 해보시면서 반복문과 함수에 대해서 개념을 정리해보시길 추천합니다.

이상으로 이번 포스팅은 마치겠습니다. 추가 의견이나 수정이 필요한 부분이 있다면 언제든지 거침없는 피드백 부탁드립니다! 부족한 글 읽어주셔서 감사합니다!

Reference

댓글