람다 함수 또는 중첩 함수 ( 'def') 중 어느 것이 더 선호됩니까?


101

나는 주로 람다 함수를 사용하지만 때로는 동일한 동작을 제공하는 중첩 함수를 사용합니다.

다음은 둘 중 하나가 다른 함수 내에서 발견 된 경우 기능적으로 동일한 작업을 수행하는 몇 가지 간단한 예입니다.

Lambda 함수

>>> a = lambda x : 1 + x
>>> a(5)
6

중첩 함수

>>> def b(x): return 1 + x

>>> b(5)
6

하나를 다른 것보다 사용하면 장점이 있습니까? (성능? 가독성? 한계? 일관성? 등)

그것이 중요합니까? 그렇지 않으면 파이썬 원칙에 위배됩니다.

이를 수행하는 분명한 방법은 하나 (가급적이면 하나만) 여야합니다 .

답변:


105

lambda이름 에 할당해야하는 경우 def대신 a를 사용하십시오. defs는 할당에 대한 구문 설탕이므로 결과는 동일하며 훨씬 더 유연하고 읽기 쉽습니다.

lambdas는 한 번만 사용할 수 있으며 이름이없는 함수는 버릴 수 있습니다 .

그러나이 사용 사례는 매우 드뭅니다. 명명되지 않은 함수 개체를 전달할 필요가 거의 없습니다.

내장 map()filter()함수 객체가 필요하지만 목록 이해생성기 표현식 은 일반적으로 해당 함수보다 더 읽기 쉽고 람다없이 모든 사용 사례를 다룰 수 있습니다.

사례를 들어 당신은 정말 당신이 사용한다, 작은 함수 객체를 필요로 operator같은 모듈 기능을 operator.add대신lambda x, y: x + y

아직 lambda다루지 않은 부분이 필요한 경우 def더 읽기 쉽게을 작성하는 것이 좋습니다. 함수가 operator모듈 의 함수보다 복잡하다면 a def가 더 좋습니다.

따라서 실제 lambda사용 사례는 매우 드뭅니다.


9
내가 사용하는 경우에 대한 대답에 동의 lambda하지만, 난이 "매우 드문"이라고 동의, 그것은에 주요 기능에 대한 일반적인 sorted또는 itertools.groupby등, 예를 들면sorted(['a1', 'b0'], key= lambda x: int(x[1]))
Chris_Rands

30

실제로 나에게는 두 가지 차이점이 있습니다.

첫 번째는 그들이 무엇을하고 무엇을 반환하는지에 관한 것입니다.

  • def는 아무것도 반환하지 않고 로컬 네임 스페이스에 '이름'을 생성하는 키워드입니다.

  • lambda는 함수 객체를 반환하고 로컬 네임 스페이스에 '이름'을 만들지 않는 키워드입니다.

따라서 함수 객체를받는 함수를 호출해야하는 경우 파이썬 코드 한 줄에서이를 수행하는 유일한 방법은 람다를 사용하는 것입니다. def와 동등한 것은 없습니다.

일부 프레임 워크에서 이것은 실제로 매우 일반적입니다. 예를 들어, 저는 Twisted 를 많이 사용합니다.

d.addCallback(lambda result: setattr(self, _someVariable, result))

매우 일반적이며 람다와 더 간결합니다.

두 번째 차이점은 실제 기능이 무엇을 할 수 있는지에 관한 것입니다.

  • 'def'로 정의 된 함수는 모든 파이썬 코드를 포함 할 수 있습니다.
  • 'lambda'로 정의 된 함수는 표현식으로 평가되어야하므로 print, import, raise, ...와 같은 문을 포함 할 수 없습니다.

예를 들면

def p(x): print x

예상대로 작동하지만

lambda x: print x

SyntaxError입니다.

물론 , 또는 로 대체 print하는 해결 방법이 있습니다 . 그러나 일반적으로이 경우 함수를 사용하는 것이 좋습니다.sys.stdout.writeimport__import__


22

이 인터뷰에서 Guido van Rossum은 Python에 'lambda'를 사용하지 않았 으면 좋겠다고 말했습니다.

" Q. Python의 어떤 기능이 가장 마음에 들지 않습니까?

때때로 저는 기여를 너무 빨리 받아들이고 나중에 그것이 실수라는 것을 깨달았습니다. 한 가지 예로 람다 함수와 같은 함수형 프로그래밍 기능 중 일부를들 수 있습니다. lambda 은 작은 익명 함수를 만들 수있는 키워드입니다. map, filter 및 reduce와 같은 내장 함수는 목록과 같은 시퀀스 유형에 대해 함수를 실행합니다.

실제로는 그렇게 잘되지 않았습니다. Python에는 로컬 및 글로벌의 두 가지 범위 만 있습니다. 이로 인해 람다가 정의 된 범위의 변수에 액세스하기를 원하기 때문에 람다 함수를 작성하는 것이 어렵지만 두 범위 때문에 불가능합니다. 이 문제를 피할 수있는 방법이 있지만 약간의 문제입니다. 종종 파이썬에서는 람다 함수를 엉망으로 만드는 대신 for 루프를 사용하는 것이 훨씬 쉬워 보입니다. 지도와 친구는 원하는 것을 수행하는 내장 기능이 이미있을 때만 잘 작동합니다.

IMHO, Iambdas는 때때로 편리 할 수 ​​있지만 일반적으로 가독성을 희생하여 편리합니다. 이것이 무엇을하는지 말해 줄 수 있습니까?

str(reduce(lambda x,y:x+y,map(lambda x:x**x,range(1,1001))))[-10:]

나는 그것을 썼고 그것을 알아내는 데 1 분이 걸렸습니다. 이것은 Project Euler에서 가져온 것입니다. 스포일러가 싫기 때문에 어떤 문제가 있는지 말하지 않겠습니다.하지만 0.124 초만에 실행됩니다. :)


20
인터뷰는 다소 오래되었고 Python은 중첩 된 범위를 추가 한 지 오래되었으므로 람다에 대한 주장이 더 이상 관련이 없습니다. 나는 그가 여전히 람다를 후회한다고 확신하지만 파이썬 3.0에서 그것을 제거하기에 충분하지 않습니다.
Thomas Wouters

10
실제로 귀하의 예제는 람다가 아니라 한 줄에 대한 논쟁이어야합니다. 또한 람다로 줄이는 대신 내장 sum 함수를 사용해야합니다. str (sum (map (lambda x : x ** x, range (1001)))) [:-10]
Triptych

2
@ThomasWouters : lambda3.0에서 제거되지 않는 것이 가까운 일이며 Guido가 그것을 지키기 위해 싸우지 않았다는 것을 이해합니다.
Ethan Furman 2014

11

n = 1000의 경우 함수와 람다를 호출하는 시간이 있습니다.

In [11]: def f(a, b):
             return a * b

In [12]: g = lambda x, y: x * y

In [13]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    f(a, b)
   ....:
100 loops, best of 3: 285 ms per loop

In [14]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    g(a, b)
   ....:
100 loops, best of 3: 298 ms per loop

In [15]: %%timeit -n 100
for a in xrange(n):
  for b in xrange(n):
    (lambda x, y: x * y)(a, b)
   ....:
100 loops, best of 3: 462 ms per loop

3
람다와 정의 된 버전이 거의 동일하다는 점이 흥미 롭습니다. 마지막 테스트는 파이썬이 람다 함수를 정의 할 때마다 공간을 할당해야했기 때문에 더 많은 시간이 걸렸습니다.
hlin117 2014

정의가 (변경되었을 수있는) 지역 변수를 참조 할 수 있기 때문에 이것이 의미가 있다고 생각합니다 ...하지만 여기처럼 그렇지 않은 경우 cpython이 더 나은 일을 할 수 있습니다.
Andy Hayden 2014

dis.dis 사용; 귀하의 (람다 x, y : x * y)는 모든 루프를 생성합니다. 루프 이전에 람다를 생성하는 경우 (일명 f = 람다 x, y : x * y) 함수 호출을위한 바이트 코드는 이전 예제의 g / f와 똑같으므로 람다 성능은 동일합니다. def 함수로. 따라서 람다 또는 def를 동일하게 사용하면 영향을 미치지 않습니다. 역으로 수행하고 루프 내에서 f () 함수를 선언 한 다음 호출합니다 ...
tito

나는 @tito 그 3 시간 제한 예 ... 보여 정확히 무엇 믿습니다
앤디 헤이든

@tito 오, 당신은 루프에서 함수를 정의한다고 말하고 있지만 나는 그것이 특이한 패턴이라고 주장합니다. 확실하지이 그 의견에 downvote ... 필요한 이유
앤디 헤이든을

7

공연:

와 함수를 만들기 lambda입니다 약간 빠른 그것을 만드는 것보다 def. 차이점은 deflocals 테이블에 이름 항목 을 생성하기 때문 입니다. 결과 함수는 동일한 실행 속도를 갖습니다.


가독성 :

Lambda 함수는 대부분의 Python 사용자에게 다소 읽기 어렵지만 일부 상황에서는 훨씬 더 간결합니다. 비 기능적 사용에서 기능적 루틴으로 변환하는 것을 고려하십시오.

# Using non-functional version.

heading(math.sqrt(v.x * v.x + v.y * v.y), math.atan(v.y / v.x))

# Using lambda with functional version.

fheading(v, lambda v: math.sqrt(v.x * v.x + v.y * v.y), lambda v: math.atan(v.y / v.x))

# Using def with functional version.

def size(v):
    return math.sqrt(v.x * v.x + v.y * v.y)

def direction(v):
    return math.atan(v.y / v.x)

deal_with_headings(v, size, direction)

보시다시피 기능 버전으로 변환하려면 원래의 비 기능 버전 lambda에만 추가하면된다는 점에서 버전이 더 짧고 "더 쉽습니다" lambda v:. 또한 훨씬 더 간결합니다. 그러나 많은 Python 사용자가 람다 구문으로 인해 혼란 스러울 것이므로 길이와 실제 복잡성에서 잃은 부분은 동료 코더의 혼란으로 인해 다시 얻을 수 있습니다.


제한 사항 :

  • lambda 함수는 변수 이름에 지정되지 않는 한 한 번만 사용할 수 있습니다.
  • lambda변수 이름에 할당 된 함수는 함수보다 이점이 없습니다 def.
  • lambda 기능은 피클하기 어렵거나 불가능할 수 있습니다.
  • def 함수의 이름은 합리적으로 설명적이고 고유하거나 적어도 범위에서 사용되지 않도록 신중하게 선택해야합니다.

일관성:

파이썬은 대부분 절차적이고 단순한 객관적 의미를 선호하는 함수형 프로그래밍 규칙을 피합니다. lambda조작이 직접 바이어스 대조를 이룬다. 또한, 이미 유행의 대안으로 deflambda기능은 구문에 다양성을 추가합니다. 일부는 덜 일관성이 있다고 생각할 것입니다.


기존 기능 :

다른 사람들이 언급했듯이 lambda필드에서의 많은 사용은 operator또는 다른 모듈의 구성원으로 대체 될 수 있습니다 . 예를 들면 :

do_something(x, y, lambda x, y: x + y)
do_something(x, y, operator.add)

기존 함수를 사용하면 대부분의 경우 코드를 더 읽기 쉽게 만들 수 있습니다.


파이썬 원칙 :“한 가지, 바람직하게는 한 가지 분명한 방법이 있어야합니다.”

그것은 진리단일 소스 와 유사합니다 . 안타깝게도 단일 명백한 실행 방법 원칙은 항상 진정한지도 교장 이라기보다는 Python에 대한 더 비참한 열망이었습니다. Python의 매우 강력한 배열 이해를 고려하십시오. mapfilter기능 과 기능적으로 동일 합니다.

[e for e in some_array if some_condition(e)]
filter(some_array, some_condition)

lambda그리고 def동일합니다.

그것은 의견의 문제이지만, 분명히 어떤 것도 깨뜨리지 않는 일반적인 사용을위한 파이썬 언어의 모든 것은 "파이 토닉"으로 충분하다고 말할 것입니다.


7

더 바람직 : 람다 함수 또는 중첩 함수 ( def)?

정규 함수에 비해 람다를 사용하면 한 가지 이점이 있습니다. 식에서 생성된다는 것입니다.

몇 가지 단점이 있습니다.

  • 이름 없음 (단지 '<lambda>')
  • 독 스트링 없음
  • 주석 없음
  • 복잡한 진술 없음

또한 둘 다 동일한 유형의 객체입니다. 이러한 이유로 저는 일반적으로 def람다 대신 키워드로 함수를 생성하는 것을 선호합니다 .

첫 번째 요점-동일한 유형의 객체입니다.

람다는 일반 함수와 동일한 유형의 객체를 생성합니다.

>>> l = lambda: 0
>>> type(l)
<class 'function'>
>>> def foo(): return 0
... 
>>> type(foo)
<class 'function'>
>>> type(foo) is type(l)
True

람다는 함수이기 때문에 일류 객체입니다.

람다와 함수 :

  • 인수로 전달할 수 있습니다 (일반 함수와 동일).
  • 외부 함수 내에서 생성되면 해당 외부 함수의 지역에 대한 클로저가됩니다.

그러나 람다는 기본적으로 함수가 전체 함수 정의 구문을 통해 얻는 일부 항목이 누락되었습니다.

람바 __name__'<lambda>'

Lambda는 결국 익명의 함수이므로 자신의 이름을 모릅니다.

>>> l.__name__
'<lambda>'
>>> foo.__name__
'foo'

따라서 람다는 네임 스페이스에서 프로그래밍 방식으로 조회 할 수 없습니다.

이것은 특정 사항을 제한합니다. 예를 들어 foo직렬화 된 코드로 검색 l할 수 있지만 다음은 검색 할 수 없습니다.

>>> import pickle
>>> pickle.loads(pickle.dumps(l))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <function <lambda> at 0x7fbbc0464e18>: 
attribute lookup <lambda> on __main__ failed

foo자체 이름을 알고 있기 때문에 잘 조회 할 수 있습니다 .

>>> pickle.loads(pickle.dumps(foo))
<function foo at 0x7fbbbee79268>

Lambda에는 주석과 독 스트링이 없습니다.

기본적으로 람다는 문서화되어 있지 않습니다. foo더 잘 문서화되도록 다시 작성해 보겠습니다 .

def foo() -> int:
    """a nullary function, returns 0 every time"""
    return 0

이제 foo에는 문서가 있습니다.

>>> foo.__annotations__
{'return': <class 'int'>}
>>> help(foo)
Help on function foo in module __main__:

foo() -> int
    a nullary function, returns 0 every time

반면, 람다에 동일한 정보를 제공하는 동일한 메커니즘이 없습니다.

>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda (...)

그러나 우리는 그들을 해킹 할 수 있습니다 :

>>> l.__doc__ = 'nullary -> 0'
>>> l.__annotations__ = {'return': int}
>>> help(l)
Help on function <lambda> in module __main__:

<lambda> lambda ) -> in
    nullary -> 0

그러나 도움말의 출력을 엉망으로 만드는 오류가있을 수 있습니다.

Lambda는 표현식 만 반환 할 수 있습니다.

Lambda는 복잡한 문을 반환 할 수없고 표현식 만 반환합니다.

>>> lambda: if True: 0
  File "<stdin>", line 1
    lambda: if True: 0
             ^
SyntaxError: invalid syntax

식은 분명히 다소 복잡 할 수 있으며 매우 열심히 시도 하면 람다로도 동일한 결과를 얻을 수 있지만 복잡성이 추가되면 명확한 코드를 작성하는 데 더 해가됩니다.

명확성과 유지 보수성을 위해 Python을 사용합니다. 람다를 과도하게 사용하면이를 막을 수 있습니다.

람다 의 유일한 장점 : 단일 표현식으로 생성 가능

이것이 가능한 유일한 장점입니다. 식으로 람다를 만들 수 있으므로 함수 호출 내에서 만들 수 있습니다.

함수 호출 내에서 함수를 생성하면 다른 곳에서 생성 된 이름에 비해 (비싸지 않은) 이름 조회를 피할 수 있습니다.

그러나 Python은 엄격하게 평가되기 때문에 이름 조회를 피하는 것 외에 다른 성능 향상은 없습니다.

매우 간단한 표현을 위해 람다를 선택할 수 있습니다.

나는 또한 대화 형 파이썬을 할 때 람다를 사용하여 여러 줄을 피하는 경향이 있습니다. 호출 할 때 생성자에 인수를 전달하려면 다음과 같은 코드 형식을 사용합니다 timeit.repeat.

import timeit

def return_nullary_lambda(return_value=0):
    return lambda: return_value

def return_nullary_function(return_value=0):
    def nullary_fn():
        return return_value
    return nullary_fn

그리고 지금:

>>> min(timeit.repeat(lambda: return_nullary_lambda(1)))
0.24312214995734394
>>> min(timeit.repeat(lambda: return_nullary_function(1)))
0.24894469301216304

나는 위의 약간의 시간 차이가에서 이름 검색에 기인 할 수 있다고 믿는다 return_nullary_function는 것을 참고 - 아주 무시할.

결론

Lambda는 특이점을 만들기 위해 코드 줄을 최소화하려는 비공식적 인 상황에 적합합니다.

Lambda는 나중에 올 코드 편집자에게 명확성이 필요한보다 공식적인 상황, 특히 중요하지 않은 경우에 적합하지 않습니다.

우리는 물체에 좋은 이름을 부여해야한다는 것을 알고 있습니다. 물체가 없을 때 어떻게 그렇게 할 수 있습니까? 이름 있습니까?

이러한 모든 이유로 저는 일반적으로 with def대신에 함수를 만드는 것을 선호합니다 lambda.


6

저는 nosklo의 조언에 동의합니다. 함수에 이름을 지정해야하는 경우 def. lambda간단한 코드를 다른 함수에 전달하는 경우를 위해 함수를 예약 합니다. 예 :

a = [ (1,2), (3,4), (5,6) ]
b = map( lambda x: x[0]+x[1], a )

3
대부분의 맵 / 람다 조합에서 목록 이해력 또는 더 적절한 기능으로 대체 할 수 있습니다. 예 : "map (sum, a)"또는 "[x [0] + x [1] for x in a]"
John Millikin

네, 사실입니다. 때때로 나는 map ()을 선호합니다. 이것은 대부분 인라인 함수를 사용하는 인위적인 예일뿐입니다.
Dan Lenski

정확히 ... 대부분의 예는 사용하는 것이 부자연스럽고 대부분의 경우 실질적으로 더 나은 방법이 있기 때문에 고안된 것입니다.
nosklo

5

다른 답변에 동의하지만 때로는 더 읽기 쉽습니다. 다음 lambda은 유용한 예 입니다. 사용 사례에서 계속 N 차원을 접하게 defaultdict됩니다.
예를 들면 다음과 같습니다.

from collections import defaultdict
d = defaultdict(lambda: defaultdict(list))
d['Foo']['Bar'].append(something)

def두 번째 차원을 만드는 것보다 더 읽기 쉽습니다. 이것은 더 높은 차원에서 훨씬 더 중요합니다.


from functools import partial; defaultdict(partial(defaultdict, list)). 두 번 이상 사용하려면 부분을 이름에 지정하십시오. 그러나이 구조 를 계속 만나면 건조하지 않은 것입니다. 유틸리티 라이브러리에 포함 시키십시오. 이 구조를 사용하여 다른 functools (또는 루프 또는 재귀)를 사용하여 임의의 n 차원 기본값을 만들 수 있습니다.
DylanYoung

3

람다의 주된 용도는 항상 간단한 콜백 함수와 함수를 인수로 필요로하는 map, reduce, filter에 사용되었습니다. 목록 이해가 표준이되고 다음과 같은 경우 추가가 허용됩니다.

x = [f for f in range(1, 40) if f % 2]

일상에서 람다를 사용하는 실제 사례를 상상하기 어렵습니다. 결과적으로 람다를 피하고 중첩 된 함수를 만듭니다.


3

람다의 중요한 제한은 표현식 외에는 아무것도 포함 할 수 없다는 것입니다. 람다식이 사소한 부작용 외에 어떤 것도 생성하는 것은 거의 불가능합니다. 왜냐하면 그것은 def'ed 함수 만큼 풍부한 신체를 가질 수 없기 때문 입니다.

즉, Lua는 익명 함수를 광범위하게 사용하는 방식으로 프로그래밍 스타일에 영향을 미쳤으며 코드를 함께 흩뿌립니다. 무엇보다 맵 / 축소를 추상 연산자로 생각하는 경향이 있는데, 목록 이해 나 생성자를 고려하지 않는 방식으로, 마치 해당 연산자를 사용하여 구현 결정을 명시 적으로 연기하는 것처럼 보입니다.

편집 : 이것은 꽤 오래된 질문이며 문제에 대한 내 의견이 다소 변경되었습니다.

우선, lambda변수에 식을 할당하는 것에 대해 강하게 편향되어 있습니다 . 파이썬은이를위한 특별한 구문을 가지고 있습니다 (힌트, def). 그 외에도 람다의 많은 용도는 이름을 얻지 못하더라도 미리 정의 된 (더 효율적인) 구현을 가지고 있습니다. 예를 들어, 문제의 예제 (1).__add__lambda또는 로 래핑 할 필요없이 just로 축약 될 수 있습니다 def. operator, itertoolsfunctools모듈 의 일부 조합으로 다른 많은 일반적인 용도를 충족 할 수 있습니다 .


1
(1).__add__-dunder 메서드를 직접 호출하는 일은 거의 발생하지 않아야합니다. 천은 lambda각 직접 던더 호출에 대해이야.
Ethan Furman 2014

1
@EthanFurman : 글쎄, 내 경험상 자연에 대한 부름 (1).__add__은 다소 드물지만 나는 "해야한다"에 가까운 곳으로 가지 않을 것이다. 의심 할 여지없이, 나는 전자가 lambda x: 1 + x. 우리가 haskells 슬라이스 표기법과 더 유사한 것을 가지고 있다면 (1+)그것은 훌륭 할 것입니다. 그러나 우리는 의미 적으로 정확히 그 것, 즉 dunder 메소드 이름으로해야합니다.
SingleNegationElimination 2014-04-24

2
  • 계산 시간.
  • 이름없는 기능.
  • 하나의 기능을 달성하고 많은 기능을 사용합니다.

간단한 예를 들어 보면

# CREATE ONE FUNCTION AND USE IT TO PERFORM MANY OPERATIONS ON SAME TYPE OF DATA STRUCTURE.
def variousUse(a,b=lambda x:x[0]):
    return [b(i) for i in a]

dummyList = [(0,1,2,3),(4,5,6,7),(78,45,23,43)]
variousUse(dummyList)                           # extract first element
variousUse(dummyList,lambda x:[x[0],x[2],x[3]]) # extract specific indexed element
variousUse(dummyList,lambda x:x[0]+x[2])        # add specific elements
variousUse(dummyList,lambda x:x[0]*x[2])        # multiply specific elements

1

로컬 범위의 변수에 람다를 할당하려는 경우 def를 사용하는 것이 좋습니다. def는 더 읽기 쉽고 나중에 더 쉽게 확장 할 수 있기 때문입니다.

fun = lambda a, b: a ** b # a pointless use of lambda
map(fun, someList)

또는

def fun(a, b): return a ** b # more readable
map(fun, someList)

둘 다 from operator import pow;map(pow, someList)(a**b for a,b in someList)훨씬 더 읽기 쉽습니다.
InQβ

1

내가 찾은 람다의 한 가지 용도는 디버그 메시지에 있습니다.

람다가 느리게 평가 될 수 있으므로 다음과 같은 코드를 가질 수 있습니다.

log.debug(lambda: "this is my message: %r" % (some_data,))

아마도 비싼 대신 :

log.debug("this is my message: %r" % (some_data,))

디버그 호출이 현재 로깅 수준으로 인해 출력을 생성하지 않더라도 형식 문자열을 처리합니다.

물론 설명 된대로 작동하려면 사용중인 로깅 모듈이 람다를 "지연 매개 변수"로 지원해야합니다 (내 로깅 모듈이 수행하는 것처럼).

온 디맨드 콘텐츠 가치 창출을위한 지연 평가의 다른 경우에도 동일한 아이디어가 적용될 수 있습니다.

예를 들어 다음 사용자 지정 삼항 연산자 :

def mif(condition, when_true, when_false):
    if condition:
         return when_true()
    else:
         return when_false()

mif(a < b, lambda: a + a, lambda: b + b)

대신에:

def mif(condition, when_true, when_false):
    if condition:
         return when_true
    else:
         return when_false

mif(a < b, a + a, b + b)

람다를 사용하면 조건에 의해 선택된 표현식 만 평가되고 람다가 없으면 둘 다 평가됩니다.

물론 간단하게 람다 대신 함수를 사용할 수 있지만, 짧은 표현의 경우 람다는 (c) 더 가볍습니다.


1
NB logging에는 이미 지연 포맷이 있습니다. log.debug("this is my message: %r", some_data)메시지가 요청 된 경우에만 포맷됩니다.
j08lue

@ j08lue 람다 메서드는 디버그 출력이 생성되지 않은 경우 모든 평가를 건너 뜁니다.이 경우 some_data값 비싼 식 또는 함수 / 메서드 호출 일 수 있습니다.
Glushiator 19

0

나는 nosklo에 동의합니다. 그건 그렇고, 한 번 사용 하더라도 기능을 버리십시오 . 대부분의 경우 연산자 모듈에서 무언가를 사용하고 싶습니다.

예 :

myFunction (data, callback function)이라는 시그니처가있는 함수가 있습니다.

2 개의 요소를 추가하는 함수를 전달하려고합니다.

람다 사용 :

myFunction(data, (lambda x, y : x + y))

비단뱀적인 방법 :

import operator
myFunction(data, operator.add)

또는 이것은 간단한 예제이지만, list 및 dict에 대한 항목 setter / getter를 포함하여 연산자 모듈이 제공하는 많은 항목이 있습니다. 정말 멋진.


-1

가장 큰 차이점은 def함수를 인라인으로 사용할 수 없다는 것입니다 . 이것은 제 생각에 lambda함수 의 가장 편리한 사용 사례입니다 . 예를 들어 개체 목록을 정렬하는 경우 :

my_list.sort(key=lambda o: o.x)

따라서 이러한 종류의 사소한 작업에 람다 사용을 유지하는 것이 좋습니다.이 작업은 함수 이름을 지정하여 제공되는 자동 문서의 혜택을받지 못합니다.


-2

람다는 새 함수를 생성하는 데 유용합니다.

>>> def somefunc(x): return lambda y: x+y
>>> f = somefunc(10)
>>> f(2)
12
>>> f(4)
14
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.