lambda, map, filter 같은 경우는 사실 가독성 부분에서 좋지 않다는 생각이 들어 지양하고 있었는데 장점이 있어서 정리해 봅니다.

lambda(람다) 함수

lambda (이후 '람다'라고 호칭)함수는 익명함수로 메모리를 절약하는 이점이 있습니다. 또한 가독성을 향상시킨다 라고도 나오지만 함수와 비교했을 때 가독성이 좋은건지는 잘 모르겠습니다. (개인적인 의견)

일반적인 함수는 객체를 만들고, 재사용을 위해 함수 이름(메모리)를 할당을 합니다.

# lambda 인수1, 인수2, ... : 인수를 이용한 표현식
sum = lambda a, b: a+b
result = sum(3,4)
print(result)
# 7

왜 사용할까?

익명함수이기 때문에 한번 쓰이고 다음줄로 넘어가면 힙(heap) 메모리 영역에서 증발하게 됩니다. (단발성으로 사용하게 될 때 유용)

자세하게 설명하자면 파이썬에서 모든 것이 객체로 관리되고 각 객체는 레퍼런스 카운터를 갖게 되는데 해당 카운터가 0 - 어떤 것도 참조를 하지 않게 되면 메모리를 환원하게 됩니다. - 이러한 역할을 하는 것이 가비지 컬렉터입니다.

모든 람다 함수가 사용 후 메모리에서 증발할까?

위의 예시와 같은 경우는 람다함수(객체)를 sum이라는 변수에 저장합니다. 위의 설명대로라면 sum()를 사용 후 다음 줄에서 삭제가 되어야 하지만 실제로는 삭제되지 않습니다. sum이라는 변수의 메모리에 람다함수의 메모리가 저장되어 있어있기 때문입니다. 람다함수가 사용 후 메모리에서 증발하기 위해선 함수의 인자값에 전달 되었을 때 증발하게 됩니다. 또 함수 내부에서 사용하는 람다일 경우 해당 함수가 종료되는 순간 메모리에서 증발합니다.

map 함수

내장함수이며 입력받은 자료형의 각 요소가 함수에 의해 수행된 결과를 묶어서 map iterator 객체로 반환합니다. map함수는 게으른 연산을 진행해서 메모리를 크게 절약할 수 있습니다. 게으른 연산을 진행하기 때문에 값을 한번 사용하면 사용했던 값은 다시 호출할 수가 없습니다.

# map(function, iterable)
# 예시
li = [1, 2, 3]
result = list(map(lambda i: i ** 2 , li))
print(result)
print(result)


# [1, 4, 9]
# result

게으른 연산(lazy evaluation)이란?

필요할 때만 가져다 사용합니다. 보통 iterator 객체들이 게으른 함수입니다. (아닐 수도 있음 )

iterator 객체

  • next() 메소드로 데이터를 순차적으로 호출 가능
  • 마지막 데이터 이후 next()를 호출하면 StopIteration 에러 발생
  • for 문을 사용할 때, 파이썬 내부에서는 임시로 list를 iterator로 변환해서 사용

iterator 예시

map()

li = [1, 2, 3]
result = map(lambda i: i * i, li)

print(type(result))


print(next(result))
print(next(result))
print(next(result))

# next(result) # StopIteration 발생


# 결과
# <class 'map'>
# 1
# 4
# 9

iter()

li = [1, 2, 3]
result = iter(li)

print(type(result))

print(next(result))
print(next(result))
print(next(result))
# next(result) # StopIteration 발생



# 결과
# <class 'list_iterator'>
# 1
# 2
# 3

generator expression

li = [1, 2, 3]
result = (val*val for val in li)

print(type(result))

print(next(result))
print(next(result))
print(next(result))
# next(result) # StopIteration 발생


# 결과
# <class 'generator'>
# 1
# 4
# 9


  1. 현승우 2019.01.16 21:01

    안녕하세요 lambda 설명하실 때
    ' 익명함수이기 때문에 한번 쓰이고 다음줄로 넘어가면 힙(heap) 메모리 영역에서 증발하게 된다. '
    라고 하셨는데 sum 이라는 객체에 선언했기 때문에 예시에서는 증발하지 않는 것이 맞는지 질문 드립니다.
    다른 함수들의 func인자에 lambda를 쓰는 경우에만 사용하고 나면 증발하게 되는 것 아닌가요?

    • 불곰1 2019.01.16 23:15 신고

      안녕하세요.

      말씀하신 부분이 정확하게 맞는 것 같습니다. sum 이라는 변수에 익명함수의 주소 값을 넣게 되므로 사용 후 다음 줄로 넘어가도 메모리에서 사라지지 않는 것을 확인했습니다.
      예시를 주신 것처럼 함수의 인자값에 lambda를 사용해야 메모리에서 삭제가 됩니다.

      좋은 의견 감사합니다.

+ Random Posts