본문 바로가기
Programming/Python

14. 함수 고급(람다, 튜플)

by IT learning 2021. 3. 20.
728x90

이번에는 파이썬만 존재하는 함수를 조금 더 편리하게끔 사용하게 도와주는 기능들을 소개하겠다.

 

튜플

튜플(Tuple)은 리스트와 비슷한 자료형이다.

하지만 리스트와 다른 점은 , 리스트는 저장해놓은 요소들을 수정할 수 있는 반면, 튜플은 한번 지정해놓은 요소들을 수정할 수가 없다.

아니 그러면 왜 사용하는건가? 리스트만 주구장창 쓰면 되는거 아닌가? 라는 생각을 할 수 있다.

나도 그랬으니. 근데 튜플을 사용하는 이유가 뒤에 나오니 조금만 참고 배워보자.

# 리스트와 튜플의 특이한 사용
[a,b] = [10,20]
(c,d) = (30,40)

print("a : ", a)
print("b : ", b)
print("c : ", c)
print("d : ", d)

튜플은 괄호를 이용하여 선언하고 요소를 저장한다.

위 코드는 리스트와 튜플의 선언과 출력을 보여주는 코드이다.

 

위 코드만 보면, 리스트와 다른게 없다. 이제 차이점을 줘보자.

tuple_test = 10,20,30,40,50
print("# 괄호가 없는 튜플의 값과 자료형 출력")
print("tuple_test :", tuple_test)
print("type(tuple_test): ", type(tuple_test))
print()

# 괄호가 없는 튜플 활용
a,b,c = 10,20,30

print("#괄호가 없는 튜플을 활용한 할당")
print("a : ", a)
print("b : ", b)
print("c : ", c)

튜플은 괄호가 없이 선언하고 할당할 수 있다. 괄호를 생략해도 튜플로 인식할 수 있는 경우는 괄호를 생략해도 된다.

위 코드를 보면 튜플을 괄호를 쓰지 않고 선언하고, 요소들을 추가했다. 저래도 인식이 된다.

 

아래쪽 튜플은 여러개의 튜플을 써놓고, 그 튜플들에게 요소를 추가해주었다. 그래도 인식이 된다.

위 코드의 실행결과이다.

이러한 편리함 때문에 튜플이 사용이 되는것이다.

 

다른 코드로 사용해보자.

# 변수의 값을 교환하는 튜플
a,b = 10,20

print("# 교환 전 값")
print("a:", a)
print("b:", b)
print()
# 값을 교환합니다.
a,b = b,a

print("# 교환 한 값")
print("a:", a)
print("b:", b)
print()

위 코드는 튜플로 선언된 변수들의 값을 교환하는 코드이다. 그저 a,b = b,a 라는 코드만으로도 교환이 가능하다.

 

튜플과 함수

튜플은 함수의 리턴에도 많이 사용한다.

함수의 리턴에 튜플을 사용하면 여러개의 값을 리턴하고 할당할 수 있기 때문이다.

# 여러 개의 값 리턴하기
def test() :
    return (10,20)

a,b = test()

print("a:",a)
print("b:",b)

위 코드는 test() 함수를 실행하면 10과 20이 들어있는 값을 리턴한다.

그 값을 a,b에다 할당하게 된다. 이렇게 리턴값을 여러개로 설정해도 돌아간다는것이다.

위에서 살펴본 것 처럼 괄호 없이 여러 값을 할당할 수 있는 것은 튜플만이 가능한 기능이라는것을 알아두길 바란다.

 

람다

요즘에는 함수라는 '기능'을 매개변수로 전달하는 코드를 많이 사용한다.

그리고 파이썬은 이런 코드를 좀 더 효율적으로 작성할 수 있도록 람다라는 기능을 제공한다.

 

함수의 매개변수로 함수 전달하기

일단 함수의 매개변수로 함수를 전달하는 코드를 작성해보겠다.

def call_10_times(func) :
    for i in range(10) :
        func()
        
        
def print_hello() :
    print("안녕하세요")
    
    
call_10_times(print_hello)
# 매개변수로 함수를 전달합니다.

# 프로그램을 실행하면 print_hello() 함수를 10번 실행한다.

위 코드는 두 개의 함수가 나오는데, 위 함수는 함수를 매개변수로 받는 함수.

아래 함수는 단순히 '안녕하세요' 단어를 출력하는 함수이다.

 

그리고 call_10_times() 함수에 print_hello 함수를 매개변수로 주게 된다면, 안녕하세요라는 단어가 10번 출력되게 된다.

위 코드의 실행결과이다.

 

filter() 함수와 map() 함수

함수를 매개변수로 전달하는 대표적인 표준함수로 map() 함수와 filter() 함수가 있다.

map() 함수는 리스트의 요소를 함수에 넣고 새로운 리스트를 구성해주는 함수이다.

filter() 함수는 리스트의 요소를 함수에 넣고 리턴된 값이 Ture일 경우에만, 새로운 리스트를 구성해주는 함수이다.

def power(item) :
    return item * item
def under_3(item) :
    return item < 3

list_input_a = [1,2,3,4,5]

# map() 함수를 사용한다.
output_a = map(power, list_input_a)
print("# map() 함수의 실행결과")
print("map(power, list_input_a):", output_a)
print("map(power, list_input_a):", list(output_a))
print()

# filter() 함수를 사용한다.
output_b = filter(under_3, list_input_a)
print("# filter() 함수의 실행결과")
print("filter(under_3, list_input_a):", output_b)
print("filter(under_3, list_input_a):", list(output_b))

위 코드는 map() 함수와 filter() 함수를 사용한 코드이다.

먼저 함수들을 선언해주었는데, 두 함수는 power의 경우 단순히 매개변수를 제곱하고 난 뒤의 값을 리턴하는 함수.

under_3 함수는 매개변수의 값이 3 이하일 경우 True, 아닐경우 False를 리턴하는 함수이다.

 

두 함수를 이용하여 map과 filter 함수를 이용하게 되었다.

위 코드의 실행결과이다.

map 함수의 구동방법을 아까 설명했듯이, 전체 요소를 새로운 리스트에 추가한다고 했다.

power함수를 사용했으므로, 제곱하여 리스트에 추가했다.

 

filter 함수는 리턴된 값이 True일 경우에만 추가한다고 했다.

따라서 under_3함수를 사용했으므로, 3 이하의 값만 리스트에 추가됐다.

 

두 코드에서 나오는 결과중에서 <map object...> 와 <filter object...> 라는 결과가 나오는데, 이를 제네레이터 라고 부른다.

제네레이터는 추후에 더 설명하겠다.

따라서 그냥 출력했을 경우에 제네레이터가 나오게 되어서, list() 함수를 사용하여 강제로 변환해 출력하게 되었다.

 

람다의 개념

매개변수로 함수를 전달하기 위해 함수 구문을 작성하는 것도 번거롭고, 코드 공간 낭비라는 생각이 들 수 있다.

그래서 람다 라는 개념을 생각해냈다고 한다. 람다는 간단한 함수를 쉽게 선언하는 방법 이다.

람다의 사용법은 다음과 같다.

lambda 매개변수: 리턴값

바로 이전에 보였던 코드를 람다로 다시 작성해보겠다.

power = lambda x: x * x
under_3 = lambda x: x < 3

list_input_a = [1,2,3,4,5]

output_a = map(power, list_input_a)
print("#map() 함수의 실행결과")
print("map(power,list_input_a):", output_a)
print("map(power, list_input_a):", list(output_a))
print()

output_b = filter(under_3, list_input_a)
print("#filter() 함수의 실행결과")
print("filter(under_3, list_input_a):", output_b)
print("filter(under_3, list_input_a):", list(output_b))

def 키워드로 선언했던 함수를 lambda로 바꾸고 return 키워드를 따로 쓰지 않았다는 정도의 차이가 생겼다.

근데, 람다는 간단한 함수를 쉽게 선언하는 방법이라고 했는데, 이건 def 키워드를 사용하는거나 차이가 없는 듯 하다.

그래서 람다는 아래 코드와 같이 함수의 매개변수에 곧바로 넣을 수가 있다.

# 인라인 람다
list_input_a = [1,2,3,4,5]

output_a = map(lambda x: x * x, list_input_a)
print("#map() 함수의 실행결과")
print("map(power,list_input_a):", output_a)
print("map(power, list_input_a):", list(output_a))
print()

output_b = filter(lambda x:x < 3, list_input_a)
print("#filter() 함수의 실행결과")
print("filter(under_3, list_input_a):", output_b)
print("filter(under_3, list_input_a):", list(output_b))

위 코드를 보면, map 함수의 매개변수에 lambda 를 넣은 모습이 식별된다.

이렇게 함수를 선언하지 않고, 그냥 매개변수로 때려박아도 상관이 없이 잘 돌아간다는 것이다.

이게 람다의 장점이다.

728x90

댓글

IT_learning's Commit