본문 바로가기
컴퓨터공학 언어/Python

내부 함수, reduce 함수

by KChang 2021. 10. 27.

내부 함수

내부 함수 : 함수 안에 함수가 있는 형태

lambda, map()

ex)

def outFunc(v1, v2):
    def inFunc(num1, num2):
        return num1 + num2
    return inFunc(v1, v2)
print(outFunc(10,20))

outFunc() 함수 밖에서 inFunc()함수를 호출하면 오류가 발생한다.

 

lambda 함수 : 함수를 한 줄로 간단하게 만들어 준다.

  • lambda 매개변수1, 매개변수2, ... : 매개변수를 이용한 표현식
def hap(num1, num2):
    res = num1 + num2
    return res
print(hap(10,20))
hap2 = lambda num1, num2 : num1 + num2
print(hap2(10,20))

hap3 = lambda num1 = 10, num2 = 20 : num1 + num2
print(hap3())
print(hap3(100, 200))

매개변수를 지정하지 않으면 기본 값으로 설정, 매개변수를 넘겨주면 기본값 무시

람다 함수 : 1회용의 간단한 함수를 만드는 것

람다 표현식이라고도 불리우는 이름이 없는 함수

익명 함수 : anonymous function

lambda함수

람다 함수는 매개변수와 함수의 기능만을 가진다.

(lambda [매개변수1, 매개변수2, ...] : [표현식])(인자1, 인자2, ...)

인라인 람다 함수 : 호출문 내에 람다 함수의 기능을 넣을 수 있다.

print('100과 200의 합 : ', (lambda x, y : x + y)(100, 200))

 

map() 함수

  • lambda 함수의 장점은 map() 함수와 함께 사용될 때 볼 수 있다.
  • map()은 두 개의 인수를 가지는 함수이다.
  • r = map(function, iterable, ...)
    • 첫 번째 인자 function : 함수명
    • 두 번째 인자 iterable : 한 번에 하나의 멤버를 반환할 수 있는 객체(list, str, tuple)
    • map() 함수는 function을 iterable의 모든 요소에 대해 적용하고 function에 의해 변경된 iterator를 반환
a = [1,2,3,4]
b = [17,12,11,10]
list(map(lambda x, y : x + y, a, b))

 

filter 내장 함수

여러 개의 데이터로부터 일부의 데이터만 추려낼 때 사용한다.

filter(조건 함수, 순회 가능한 데이터)

filter()함수는 두 번째 인자로 넘어온 데이터 중에서 첫 번째 인자로 넘어온 조건 함수를 만족하는 데이터만을 반환한다.

ex)

users = [{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'},
{'mail': 'hintoncynthia@hotmail.com', 'name': 'Madison Martinez', 'sex': 'F'},
{'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'},
{'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'},
{'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}]


# 함수를 인자로 받기 때문에, is_man() 함수 선언
def is_man(user):
     return user["sex"] == "M"

# 첫 번째 인자 : is_man(), 두 번째 인자 : users
for man in filter(is_man, users):
    print(man)


# 결과
# {'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}
# {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'}

 

람다 함수로 필터링

조건 함수의 코드가 긴 경우에는 위와 같이 함수를 선언하는 것이 낫겠지만, 함수가 짧은 경우에는 람다 함수를 사용하면 간단한 코드를 만들 수 있다.

users = [{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'},
{'mail': 'hintoncynthia@hotmail.com', 'name': 'Madison Martinez', 'sex': 'F'},
{'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'},
{'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'},
{'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}]


# 함수를 인자로 받기 때문에, is_man() 함수 선언
def is_man(user):
     return user["sex"] == "M"

for woman in filter(lambda u: u["sex"] != "M", users):
    print(woman)

 

결과 데이터 반환

filter() 함수로 데이터를 list나 tuple 타입으로 저장을 해야한다.

filter()함수는 filter 타입으로 결과를 리턴한다.

filter() 함수의 결과값을 list로 변환하는 가장 쉬운 방법은 list() 내장 함수를 사용하는 것이다

users = [{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'},
{'mail': 'hintoncynthia@hotmail.com', 'name': 'Madison Martinez', 'sex': 'F'},
{'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'},
{'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'},
{'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}]

print(list(filter(lambda u: u["mail"].endswith("@gmail.com"), users)))

# 결과
[{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}, {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'}, {'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'}, {'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}]

tuple() 내장 함수를 사용하면 tuple로 변환할 수 있다.

users = [{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'},
{'mail': 'hintoncynthia@hotmail.com', 'name': 'Madison Martinez', 'sex': 'F'},
{'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'},
{'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'},
{'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}]

print(tuple(filter(lambda u: u["mail"].endswith("@gmail.com"), users)))

# 결과
({'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}, {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'}, {'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'}, {'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'})

 

List Comprehension

filter() 함수를 사용하는 것보다 더 파이썬답게 데이터를 추려내는 방법이다.

users = [{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'},
{'mail': 'hintoncynthia@hotmail.com', 'name': 'Madison Martinez', 'sex': 'F'},
{'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'},
{'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'},
{'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}]

print([user for user in users if user["sex"] == 'M'])

# 결과
[{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}, {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'}]

list comprehension 결과 값은 list 타입이기 때문에, 별다른 타입 변환이 필요없다.

tuple을 얻고 싶다면 tuple() 내장 함수만 사용해주면 된다.

users = [{'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'},
{'mail': 'hintoncynthia@hotmail.com', 'name': 'Madison Martinez', 'sex': 'F'},
{'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'},
{'mail': 'daniel79@gmail.com', 'name': 'Karen Rodriguez', 'sex': 'F'},
{'mail': 'ujackson@gmail.com', 'name': 'Amber Rhodes', 'sex': 'F'}]

print(tuple(user for user in users if user["sex"] == 'M'))

# 결과
({'mail': 'gregorythomas@gmail.com', 'name': 'Brett Holland', 'sex': 'M'}, {'mail': 'wwagner@gmail.com', 'name': 'Michael Jenkins', 'sex': 'M'})

ex) 제곱 출력

a = [1,2,3,4,5]
a = [x**2 for x in a]
print(a)

# 결과
[1, 4, 9, 16, 25, 36, 49]

ex) 여러 개의 정수 문자열을 입력받아 이를 int()함수를 사용해서 정수형 값을 가진 리스트로 변환

list_array = [int(x) for x in input('정수를 여러개 입력하세요 : ').split()]

print(list_array)

ex) 두 리스트의 곱하기 기능

product_xy = [x * y for x in [1, 2, 3] for y in [2, 4, 6]]

# 결과
[2, 4, 6, 4, 8, 12, 6, 12, 18]

ex) 2와 3의 배수 구하기

name = [n for n in range(1, 31) if n % 2 == 0 if n % 3 == 0]
print(name)

# 결과
[6, 12, 18, 24, 30]

 

추가적 필터(filter) 함수

1) 함수 범위 및 조건 지정할 때 filter 함수 사용

ages = [34, 39, 29, 19, 13, 44]

print('성년 리스트 : ')
for a in filter(lambda x : x >= 19, ages):
    print(a, end = ' ')

2) 람다 함수를 이용한 음수 값 추출 기능

n_list = [-30, 45, -5, -90, 20, 54, 77]

minus_list = list(filter(lambda  x : x < 0, n_list))
print("음수 리스트",minus_list)

 

 

reduce 함수

def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        value = next(it)
    else:
        value = initializer
    for element in it:
        value = function(value, element)
    return value

reduce 함수는 function, iterable은 반드시 전달해줘야 하고, initializer는 선택적이다.

reduce 함수는 iterable의 요소들을 function에 대입하여 하나의 결과값을 리턴해주는 함수이다.

ex) function : func, iterable : [a_1, a_2, a_3, a_4]

리턴하는 결과 값 : func(func(func(a_1, a_2), a_3), a_4)

 

def reduce(function, iterable, initializer=None):
    it = iter(iterable)
    if initializer is None:
        value = next(it)
    else:
        value = initializer
    for element in it:
        value = function(value, element)
    return value

result1 = reduce(lambda  x, y : x + y, ['2','4','6','8','10','12'],'add : ')
print(result1)


# 결과
add : 24681012

 

 


참고 자료

'컴퓨터공학 언어 > Python' 카테고리의 다른 글

파일 입출력  (0) 2021.10.28
iterator, generator  (0) 2021.10.27
Algorithm 공부하다 알게된 내용  (0) 2021.10.26
Module과 Package  (0) 2021.10.15
함수  (0) 2021.10.15

댓글