2009-10-18 35 views
13

Bạn có thể đưa ra một ví dụ và các ví dụ khác cho thấy khi nào và khi nào không sử dụng Lambda? Cuốn sách của tôi cho tôi các ví dụ, nhưng chúng gây nhầm lẫn."lambda" có nghĩa là gì trong Python, và cách đơn giản nhất để sử dụng nó là gì?

+8

Phần nào của http://docs.python.org/tutorial/controlflow.html#lambda-forms gây nhầm lẫn hoặc không đầy đủ? Cuốn sách nào gây nhầm lẫn? Những phần nào của nó khó hiểu? –

Trả lời

32

Lambda, có nguồn gốc từ Lambda Calculus và (AFAIK) lần đầu tiên được triển khai tại Lisp, về cơ bản là một chức năng ẩn danh - một chức năng mà không có một cái tên, và được sử dụng trong dòng, nói cách khác bạn có thể gán một định danh cho một hàm lambda trong một biểu thức đơn như vậy:

>>> addTwo = lambda x: x+2 
>>> addTwo(2) 
4 

này gán addTwo đến chức năng ẩn danh, mà chấp nhận 1 tham số x, và trong cơ thể chức năng nó sẽ thêm 2 đến x, nó sẽ trả về giá trị cuối cùng của biểu thức cuối cùng trong nội dung hàm do đó không có từ khóa return.

Đoạn mã trên là tương đương với:

>>> def addTwo(x): 
...  return x+2 
... 
>>> addTwo(2) 
4 

Trừ bạn không sử dụng một định nghĩa hàm, bạn đang gán một định danh với lambda.

Nơi tốt nhất để sử dụng chúng là khi bạn không thực sự muốn xác định hàm có tên, có thể vì chức năng đó sẽ chỉ được sử dụng một lần và không nhiều lần, trong trường hợp này bạn sẽ tốt hơn tắt với định nghĩa hàm.

Ví dụ về một cây băm sử dụng lambdas:

>>> mapTree = { 
...  'number': lambda x: x**x, 
...  'string': lambda x: x[1:] 
... } 
>>> otype = 'number' 
>>> mapTree[otype](2) 
4 
>>> otype = 'string' 
>>> mapTree[otype]('foo') 
'oo' 

Trong ví dụ này, tôi thật sự không muốn xác định một tên cho một trong những chức năng bởi vì tôi sẽ chỉ sử dụng chúng trong băm, do đó tôi sẽ sử dụng lambdas.

+0

Chỉ cần một ít nitpick nhỏ trên một câu trả lời khác tuyệt vời: lambda không ban đầu từ Lisp, mà là từ tính toán lambda. – phoebus

+0

ah vâng, sai lầm của tôi khi sử dụng có nguồn gốc - tôi đã thực hiện một số chỉnh sửa. Bất cứ điều gì khác tôi nên thêm/sửa đổi? –

+0

+1 Câu trả lời tuyệt vời, hãy xem xét thay đổi tên 'loại' trong ví dụ dict .. vì nó được xây dựng ... –

3

Tôi không biết bạn đang sử dụng cuốn sách nào, nhưng Dive into Python has a section mà tôi nghĩ là thông tin.

+0

Trong năm 2017, không có trang web diveintopython.org bất cứ nơi nào trên World Wide Web! – Rexford

3

Sử dụng lambda là một loại kiểu. Khi bạn có thể lấy đi một hàm rất đơn giản, và thường là nơi bạn đang lưu trữ nó ở đâu đó (trong danh sách các chức năng có lẽ, hoặc trong cấu trúc dữ liệu bộ công cụ GUI, vv) mọi người cảm thấy lambda làm giảm sự lộn xộn trong mã của họ.

Trong Python, chỉ có thể tạo một lambda trả về một biểu thức duy nhất và lambda không thể mở rộng nhiều dòng (trừ khi bạn nối nhiều dòng bằng cách sử dụng dấu gạch chéo ngược-ở-cuối-của-dòng) lừa). Mọi người đã yêu cầu Python thêm các cải tiến cho lambda, nhưng nó đã không xảy ra. Như tôi đã hiểu, những thay đổi để làm cho lambda có thể viết bất kỳ hàm nào sẽ làm phức tạp đáng kể mã phân tích trong Python. Và, kể từ khi chúng tôi đã có def để xác định một chức năng, lợi ích không được coi là giá trị biến chứng. Vì vậy, có một số trường hợp mà bạn có thể muốn sử dụng lambda, nơi nó không phải là có thể. Trong trường hợp đó, bạn chỉ có thể sử dụng một số điện thoại def:

object1.register_callback_function(lambda x: x.foo() > 3) 

def fn(x): 
    if x.foo() > 3: 
     x.recalibrate() 
     return x.value() > 9 
    elif x.bar() > 3: 
     x.do_something_else() 
     return x.other_value < 0 
    else: 
     x.whatever() 
     return True 

object2.register_callback_function(fn) 
del(fn) 

Hàm gọi lại đầu tiên đơn giản và lambda đủ. Đối với thứ hai, nó chỉ đơn giản là không thể sử dụng một lambda. Chúng tôi đạt được hiệu quả tương tự bằng cách sử dụng def và tạo đối tượng hàm được gắn với tên fn và sau đó đi qua fn đến register_callback_function(). Sau đó, chỉ để hiển thị chúng tôi có thể, chúng tôi gọi số del() vào tên fn để hủy liên kết. Bây giờ tên fn không còn bị ràng buộc với bất kỳ đối tượng nào, nhưng register_callback_function() vẫn có tham chiếu đến đối tượng hàm để đối tượng hàm tồn tại.

Các vấn đề liên quan