Python ฟังก์ชันแลมบ์ดาพร้อมตัวอย่าง

ฟังก์ชั่นแลมบ์ดาคืออะไร Python?

A ฟังก์ชันแลมบ์ดาใน Python การเขียนโปรแกรมเป็นฟังก์ชันที่ไม่ระบุชื่อหรือฟังก์ชันที่ไม่มีชื่อ เป็นฟังก์ชันขนาดเล็กและจำกัดไม่ให้มีมากกว่าหนึ่งบรรทัด เช่นเดียวกับฟังก์ชันปกติ ฟังก์ชัน Lambda สามารถมีอาร์กิวเมนต์ได้หลายรายการด้วยนิพจน์เดียว

In Pythonนิพจน์แลมบ์ดา (หรือรูปแบบแลมบ์ดา) ถูกนำมาใช้เพื่อสร้างฟังก์ชันที่ไม่ระบุชื่อ โดยคุณจะใช้ไฟล์ แลมบ์ดา คำหลัก (เช่นเดียวกับที่คุณใช้ def เพื่อกำหนดฟังก์ชันปกติ) ทุกฟังก์ชันที่ไม่ระบุตัวตนที่คุณกำหนด Python จะมีส่วนสำคัญ 3 ส่วน คือ

  • คำหลักแลมบ์ดา
  • พารามิเตอร์ (หรือตัวแปรที่ถูกผูกไว้) และ
  • ฟังก์ชั่นร่างกาย

ฟังก์ชัน lambda สามารถมีพารามิเตอร์จำนวนเท่าใดก็ได้ แต่ตัวฟังก์ชันจะมีได้เพียงพารามิเตอร์เท่านั้น หนึ่ง การแสดงออก. นอกจากนี้ lambda ยังเขียนด้วยโค้ดบรรทัดเดียวและสามารถเรียกใช้ได้ทันที คุณจะเห็นการทำงานทั้งหมดนี้ในตัวอย่างที่กำลังจะมาถึง

ไวยากรณ์และตัวอย่าง

ไวยากรณ์อย่างเป็นทางการในการเขียนฟังก์ชันแลมบ์ดามีดังต่อไปนี้:

lambda p1, p2: expression

ในที่นี้ p1 และ p2 คือพารามิเตอร์ที่ส่งผ่านไปยังฟังก์ชันแลมบ์ดา คุณสามารถเพิ่มพารามิเตอร์ได้มากหรือน้อยตามที่คุณต้องการ

อย่างไรก็ตาม โปรดทราบว่าเราไม่ได้ใช้เครื่องหมายวงเล็บล้อมรอบพารามิเตอร์เหมือนกับที่เราทำกับฟังก์ชันทั่วไป ส่วนสุดท้าย (นิพจน์) คือนิพจน์ Python ที่ถูกต้องใดๆ ที่ทำงานบนพารามิเตอร์ที่คุณให้ไว้ในฟังก์ชัน

1 ตัวอย่าง

ตอนนี้คุณรู้เกี่ยวกับแลมบ์ดาแล้ว เรามาลองดูตัวอย่างกัน ดังนั้นเปิดของคุณ IDLE และพิมพ์ตามนี้:

adder = lambda x, y: x + y
print (adder (1, 2))

นี่คือผลลัพธ์:

3

คำอธิบายรหัส

ที่นี่ เรากำหนดตัวแปรที่จะเก็บผลลัพธ์ที่ส่งคืนโดยฟังก์ชันแลมบ์ดา

1. คีย์เวิร์ด lambda ที่ใช้กำหนดฟังก์ชันที่ไม่ระบุชื่อ

2. x และ y คือพารามิเตอร์ที่เราส่งผ่านไปยังฟังก์ชันแลมบ์ดา

3. นี่คือเนื้อความของฟังก์ชัน ซึ่งจะเพิ่มพารามิเตอร์ 2 ตัวที่เราส่งผ่าน โปรดสังเกตว่ามันเป็นนิพจน์เดียว คุณไม่สามารถเขียนหลายคำสั่งในเนื้อความของฟังก์ชันแลมบ์ดาได้

4. เราเรียกใช้ฟังก์ชันและพิมพ์ค่าที่ส่งคืน

2 ตัวอย่าง

นั่นเป็นตัวอย่างพื้นฐานในการทำความเข้าใจพื้นฐานและไวยากรณ์ของแลมบ์ดา ตอนนี้ลองพิมพ์แลมบ์ดาแล้วดูผลลัพธ์ เปิดของคุณอีกครั้ง IDLE และพิมพ์ตามนี้:

#What a lambda returns
string='some kind of a useless lambda'
print(lambda string : print(string))

ตอนนี้บันทึกไฟล์ของคุณแล้วกด F5 เพื่อเรียกใช้โปรแกรม นี่คือผลลัพธ์ที่คุณควรได้รับ

Output:

<function <lambda> at 0x00000185C3BF81E0>

เกิดอะไรขึ้นที่นี่? ลองดูโค้ดเพื่อทำความเข้าใจเพิ่มเติม

คำอธิบายรหัส

  1. ที่นี่เรากำหนด a เชือก ที่คุณจะส่งเป็นพารามิเตอร์ไปยังแลมบ์ดา
  2. เราประกาศแลมบ์ดาที่เรียกคำสั่งการพิมพ์และพิมพ์ผลลัพธ์

แต่ทำไมโปรแกรมไม่พิมพ์สตริงที่เราส่งผ่านล่ะ? เนื่องจากแลมบ์ดาเองก็ส่งคืนวัตถุฟังก์ชัน ในตัวอย่างนี้ แลมบ์ดาไม่ได้เป็น ที่เรียกว่า ด้วยฟังก์ชั่นการพิมพ์แต่เรียบง่าย การคืน วัตถุฟังก์ชันและตำแหน่งหน่วยความจำที่เก็บไว้ นั่นคือสิ่งที่ถูกพิมพ์ที่คอนโซล

3 ตัวอย่าง

อย่างไรก็ตาม หากคุณเขียนโปรแกรมในลักษณะนี้:

#What a lambda returns #2
x="some kind of a useless lambda"
(lambda x : print(x))(x)

และเรียกใช้โดยกด F5 คุณจะเห็นผลลัพธ์เช่นนี้

Output:

some kind of a useless lambda

ตอนนี้ แลมบ์ดากำลังถูกเรียกใช้ และสตริงที่เราส่งผ่านจะถูกพิมพ์ที่คอนโซล แต่ไวยากรณ์แปลกๆ นั้นคืออะไร และทำไมคำจำกัดความของแลมบ์ดาจึงถูกครอบคลุมในวงเล็บ มาทำความเข้าใจกันตอนนี้

คำอธิบายรหัส

  1. นี่คือสตริงเดียวกับที่เรากำหนดไว้ในตัวอย่างก่อนหน้านี้
  2. ในส่วนนี้ เรากำลังกำหนดแลมบ์ดาและเรียกมันทันทีโดยส่งสตริงเป็นอาร์กิวเมนต์ นี่คือสิ่งที่เรียกว่า IIFE และคุณจะได้เรียนรู้เพิ่มเติมในส่วนถัดไปของบทช่วยสอนนี้

4 ตัวอย่าง

มาดูตัวอย่างสุดท้ายเพื่อทำความเข้าใจวิธีดำเนินการ lambdas และฟังก์ชันปกติ ดังนั้นเปิดของคุณ IDLE และในไฟล์ใหม่ ให้พิมพ์ดังต่อไปนี้:

#A REGULAR FUNCTION
def guru( funct, *args ):
funct( *args )
def printer_one( arg ):
return print (arg)
def printer_two( arg ):
print(arg)
#CALL A REGULAR FUNCTION 
guru( printer_one, 'printer 1 REGULAR CALL' )
guru( printer_two, 'printer 2 REGULAR CALL \n' )
#CALL A REGULAR FUNCTION THRU A LAMBDA
guru(lambda: printer_one('printer 1 LAMBDA CALL'))
guru(lambda: printer_two('printer 2 LAMBDA CALL'))

ตอนนี้ให้บันทึกไฟล์แล้วกด F5 เพื่อเรียกใช้โปรแกรม หากคุณไม่ได้ทำผิดพลาด ผลลัพธ์ควรเป็นเช่นนี้

Output:

printer 1 REGULAR CALL

printer 2 REGULAR CALL

printer 1 LAMBDA CALL

printer 2 LAMBDA CALL

คำอธิบายรหัส

  1. ฟังก์ชันที่เรียกว่า guru ซึ่งรับฟังก์ชันอื่นเป็นพารามิเตอร์แรกและอาร์กิวเมนต์อื่น ๆ ที่ตามมา
  2. printer_one เป็นฟังก์ชันธรรมดาที่พิมพ์พารามิเตอร์ที่ส่งไปและส่งกลับ
  3. printer_two คล้ายกับ printer_one แต่ไม่มีคำสั่ง return
  4. ในส่วนนี้ เรากำลังเรียกใช้ฟังก์ชัน guru และส่งผ่านฟังก์ชันเครื่องพิมพ์และสตริงเป็นพารามิเตอร์
  5. นี่คือไวยากรณ์เพื่อให้บรรลุขั้นตอนที่สี่ (เช่น การเรียกใช้ฟังก์ชันกูรู) แต่ใช้แลมบ์ดา

ในส่วนถัดไป คุณจะได้เรียนรู้วิธีใช้ฟังก์ชัน lambda ด้วย แผนที่(), ลด(), และ กรอง() in Python.

การใช้แลมบ์ดาด้วย Python ในตัว

ฟังก์ชัน Lambda มอบวิธีการอันสง่างามและทรงพลังในการดำเนินการโดยใช้วิธีการในตัว Python- เป็นไปได้เนื่องจาก lambdas สามารถเรียกใช้ได้ทันทีและส่งผ่านเป็นอาร์กิวเมนต์ของฟังก์ชันเหล่านี้

IIFE เข้า Python แลมบ์ดา

IIFE ย่อมาจาก เรียกใช้ฟังก์ชันการดำเนินการทันที หมายความว่าฟังก์ชันแลมบ์ดาสามารถเรียกใช้ได้ทันทีที่มีการกำหนดไว้ มาทำความเข้าใจเรื่องนี้ด้วยตัวอย่าง ยิงคุณ IDLE และพิมพ์ตามนี้:

 (lambda x: x + x)(2)

นี่คือคำอธิบายผลลัพธ์และโค้ด:

ความสามารถของแลมบ์ดาที่จะเรียกใช้ได้ทันทีทำให้คุณสามารถใช้มันภายในฟังก์ชันเช่น map() และ ลด () มันมีประโยชน์เพราะคุณอาจไม่ต้องการใช้ฟังก์ชันเหล่านี้อีก

แลมบ์ดาในตัวกรอง ()

ฟังก์ชั่นตัวกรองใช้เพื่อเลือกองค์ประกอบเฉพาะจากลำดับขององค์ประกอบ ลำดับสามารถเป็นตัววนซ้ำใดๆ เช่น รายการ เซต สิ่งอันดับ ฯลฯ

องค์ประกอบที่จะถูกเลือกจะขึ้นอยู่กับข้อจำกัดที่กำหนดไว้ล่วงหน้า ต้องใช้ 2 พารามิเตอร์:

  • ฟังก์ชันที่กำหนดข้อจำกัดในการกรอง
  • ลำดับ (ตัววนซ้ำใดๆ เช่น รายการ สิ่งอันดับ ฯลฯ)

ตัวอย่างเช่น

sequences = [10,2,8,7,5,4,3,11,0, 1]
filtered_result = filter (lambda x: x > 4, sequences) 
print(list(filtered_result))

นี่คือผลลัพธ์:

[10, 8, 7, 5, 11]

คำอธิบายรหัส:

1. ในคำสั่งแรก เราจะกำหนดรายการที่เรียกว่าลำดับซึ่งประกอบด้วยตัวเลขบางตัว

2. ที่นี่ เราประกาศตัวแปรชื่อ filtered_result ซึ่งจะเก็บค่าที่กรองแล้วที่ส่งคืนโดยฟังก์ชัน filter()

3. ฟังก์ชันแลมบ์ดาที่ทำงานบนแต่ละองค์ประกอบของรายการและส่งกลับค่าจริงหากค่านั้นมากกว่า 4

4. พิมพ์ผลลัพธ์ที่ส่งคืนโดยฟังก์ชันตัวกรอง

แลมบ์ดาในแผนที่ ()

ฟังก์ชัน map ใช้สำหรับการดำเนินการเฉพาะกับทุกองค์ประกอบในลำดับ เช่นเดียวกับ filter() ฟังก์ชันนี้ยังรับพารามิเตอร์ 2 ตัวด้วย:

  1. ฟังก์ชั่นที่กำหนด op เพื่อดำเนินการกับองค์ประกอบ
  2. ลำดับหนึ่งหรือหลายลำดับ

ตัวอย่างเช่น นี่คือโปรแกรมที่พิมพ์ตัวเลขกำลังสองในรายการที่กำหนด:

sequences = [10,2,8,7,5,4,3,11,0, 1]
filtered_result = map (lambda x: x*x, sequences) 
print(list(filtered_result))

Output:

 [100, 4, 64, 49, 25, 16, 9, 121, 0, 1]

[KR1]

คำอธิบายรหัส:

  1. ที่นี่เราจะกำหนดรายการที่เรียกว่าลำดับซึ่งประกอบด้วยตัวเลขบางตัว
  2. เราประกาศตัวแปรชื่อ filtered_result ซึ่งจะเก็บค่าที่แมปไว้
  3. ฟังก์ชันแลมบ์ดาที่ทำงานบนแต่ละองค์ประกอบของรายการและส่งคืนค่ากำลังสองของตัวเลขนั้น
  4. พิมพ์ผลลัพธ์ที่ส่งคืนโดยฟังก์ชันแผนที่

แลมบ์ดาลด ()

ฟังก์ชัน reduce เช่น map() ใช้ในการดำเนินการกับทุกองค์ประกอบในลำดับ อย่างไรก็ตาม ฟังก์ชันนี้แตกต่างจาก map ตรงที่การทำงาน ต่อไปนี้คือขั้นตอนที่ฟังก์ชัน reduce() ปฏิบัติตามเพื่อคำนวณเอาต์พุต:

ขั้นตอน 1) ดำเนินการตามการดำเนินการที่กำหนดไว้กับ 2 องค์ประกอบแรกของลำดับ

ขั้นตอน 2) บันทึกผลลัพธ์นี้

ขั้นตอน 3) ดำเนินการด้วยผลลัพธ์ที่บันทึกและองค์ประกอบถัดไปในลำดับ

ขั้นตอน 4) ทำซ้ำจนกว่าจะไม่มีองค์ประกอบเหลืออยู่

นอกจากนี้ยังใช้พารามิเตอร์สองตัวด้วย:

  1. ฟังก์ชั่นที่กำหนดการดำเนินการที่จะดำเนินการ
  2. ลำดับ (ตัววนซ้ำใดๆ เช่น รายการ สิ่งอันดับ ฯลฯ)

ตัวอย่างเช่น นี่คือโปรแกรมที่ส่งคืนผลคูณขององค์ประกอบทั้งหมดในรายการ:

from functools import reduce
sequences = [1,2,3,4,5]
product = reduce (lambda x, y: x*y, sequences)
print(product)

นี่คือผลลัพธ์:

120

คำอธิบายรหัส:

  1. นำเข้าลดจากโมดูล functools
  2. ที่นี่เราจะกำหนดรายการที่เรียกว่าลำดับซึ่งประกอบด้วยตัวเลขบางตัว
  3. เราประกาศตัวแปรที่เรียกว่า product ซึ่งจะเก็บค่าที่ลดลง
  4. ฟังก์ชันแลมบ์ดาที่ทำงานในแต่ละองค์ประกอบของรายการ มันจะส่งคืนผลคูณของหมายเลขนั้นตามผลลัพธ์ก่อนหน้า
  5. พิมพ์ผลลัพธ์ที่ส่งคืนโดยฟังก์ชันลด

ทำไม (และทำไมไม่) ใช้ฟังก์ชันแลมบ์ดา?

ดังที่คุณจะเห็นในส่วนถัดไป lambdas จะได้รับการปฏิบัติเหมือนกับฟังก์ชันปกติในระดับล่าม ในทางหนึ่ง คุณสามารถพูดได้ว่า lambdas มีไวยากรณ์ขนาดกะทัดรัดสำหรับการเขียนฟังก์ชันซึ่งส่งคืนนิพจน์เดียว

อย่างไรก็ตาม คุณควรรู้ว่าเมื่อใดเป็นความคิดที่ดีที่จะใช้แลมบ์ดา และเมื่อใดที่ควรหลีกเลี่ยง ในส่วนนี้ คุณจะได้เรียนรู้หลักการออกแบบบางประการที่นักพัฒนา Python ใช้เมื่อเขียน lambda

หนึ่งในกรณีการใช้งานที่พบบ่อยที่สุดสำหรับ lambdas คือในการเขียนโปรแกรมเชิงฟังก์ชันเช่น Python รองรับกระบวนทัศน์ (หรือสไตล์) ของการเขียนโปรแกรมที่เรียกว่าการเขียนโปรแกรมเชิงฟังก์ชัน

ช่วยให้คุณสามารถระบุฟังก์ชันเป็นพารามิเตอร์ให้กับฟังก์ชันอื่นได้ (เช่น ในแผนที่ ตัวกรอง ฯลฯ) ในกรณีเช่นนี้ การใช้ lambda ถือเป็นวิธีที่สวยงามในการสร้างฟังก์ชันแบบครั้งเดียวและส่งผ่านเป็นพารามิเตอร์

เมื่อใดที่คุณไม่ควรใช้ Lambda

คุณไม่ควรเขียนฟังก์ชันแลมบ์ดาที่ซับซ้อนในสภาพแวดล้อมการผลิต เพราะจะทำให้ผู้เข้ารหัสที่ดูแลโค้ดของคุณถอดรหัสได้ยาก หากคุณพบว่าตัวเองกำลังสร้างนิพจน์บรรทัดเดียวที่ซับซ้อน การกำหนดฟังก์ชันที่เหมาะสมจะเป็นวิธีที่ดีกว่ามาก แนวทางปฏิบัติที่ดีที่สุดคือ คุณต้องจำไว้ว่าโค้ดที่เรียบง่ายนั้นดีกว่าโค้ดที่ซับซ้อนเสมอ

Lambdas กับฟังก์ชันปกติ

ตามที่ระบุไว้ก่อนหน้านี้ lambdas เป็นเพียงฟังก์ชันที่ไม่มีตัวระบุผูกไว้ พูดง่ายๆ ก็คือ ฟังก์ชันเหล่านี้ไม่มีชื่อ (จึงไม่ระบุชื่อ) นี่คือตารางที่แสดงความแตกต่างระหว่าง lambdas และฟังก์ชันปกติใน python

แลมบ์ดาส

ฟังก์ชั่นปกติ

ไวยากรณ์:

lambda x : x + x

ไวยากรณ์:

def (x) :
return x + x 

ฟังก์ชัน Lambda สามารถมีนิพจน์ในร่างกายได้เพียงนิพจน์เดียวเท่านั้น

ฟังก์ชันปกติสามารถมีนิพจน์และคำสั่งได้หลายรายการในร่างกาย

แลมบ์ดาไม่มีชื่อที่เกี่ยวข้องกับพวกมัน นั่นเป็นสาเหตุที่เรียกอีกอย่างว่าฟังก์ชันที่ไม่ระบุชื่อ

ฟังก์ชันปกติต้องมีชื่อและลายเซ็น

Lambdas ไม่มีคำสั่ง return เนื่องจากเนื้อหาจะถูกส่งคืนโดยอัตโนมัติ

ฟังก์ชั่นที่ต้องการคืนค่าควรมีคำสั่ง return

อธิบายความแตกต่าง?

ความแตกต่างหลักระหว่างแลมบ์ดาและฟังก์ชันปกติก็คือ ฟังก์ชันแลมบ์ดาจะประเมินเพียงนิพจน์เดียวและให้ผลลัพธ์เป็นวัตถุฟังก์ชัน ด้วยเหตุนี้ เราจึงสามารถตั้งชื่อผลลัพธ์ของฟังก์ชัน lambda และใช้ในโปรแกรมของเราได้เหมือนที่เราทำในตัวอย่างก่อนหน้านี้

ฟังก์ชันปกติสำหรับตัวอย่างข้างต้นจะมีลักษณะดังนี้:

def adder (x, y):
return x + y 
print (adder (1, 2))

ในที่นี้ เราต้องนิยาม a พร้อมชื่อ สำหรับฟังก์ชันซึ่ง รับคืน ผลลัพธ์เมื่อเรา โทรศัพท์ ฟังก์ชันแลมบ์ดาไม่มีคำสั่ง return เพราะจะมีเพียงนิพจน์เดียวที่ส่งคืนตามค่าเริ่มต้นเสมอ คุณไม่จำเป็นต้องกำหนดแลมบ์ดาด้วยซ้ำ เพราะสามารถเรียกใช้งานได้ทันที (ดูหัวข้อถัดไป) ดังที่คุณจะเห็นในตัวอย่างต่อไปนี้ แลมบ์ดาจะมีประสิทธิภาพเป็นพิเศษเมื่อเราใช้แลมบ์ดาร่วมกับ Pythonฟังก์ชันในตัวของ

อย่างไรก็ตาม คุณอาจยังคงสงสัยว่า lambdas แตกต่างจากฟังก์ชันที่ส่งคืนนิพจน์เดียวอย่างไร (เหมือนกับตัวอย่างข้างต้น) ในระดับล่ามไม่มีความแตกต่างกันมากนัก อาจฟังดูน่าประหลาดใจ แต่ฟังก์ชัน lambda ใดๆ ที่คุณกำหนดไว้ Python ล่ามจะถือเป็นฟังก์ชันปกติ

ดังที่คุณเห็นในแผนภาพ คำจำกัดความทั้งสองได้รับการจัดการในลักษณะเดียวกันโดยล่าม python เมื่อแปลงเป็น bytecode ตอนนี้คุณไม่สามารถตั้งชื่อฟังก์ชันได้ แลมบ์ดา เพราะมันถูกสงวนไว้โดย Pythonแต่ชื่อฟังก์ชันอื่นๆ จะให้ผลลัพธ์เป็น bytecode[KR6] เดียวกัน

สรุป

  • Lambdas หรือที่รู้จักกันในชื่อฟังก์ชันนิรนาม เป็นฟังก์ชันขนาดเล็กที่ถูกจำกัดซึ่งไม่จำเป็นต้องมีชื่อ (เช่น ตัวระบุ)
  • แลมบ์ดาทุกตัวทำหน้าที่ใน Python มี 3 ส่วนสำคัญ:
  • คำหลักแลมบ์ดา
  • พารามิเตอร์ (หรือตัวแปรที่ถูกผูกไว้) และ
  • ฟังก์ชั่นร่างกาย
  • ไวยากรณ์สำหรับการเขียนแลมบ์ดาคือ: พารามิเตอร์แลมบ์ดา: นิพจน์
  • Lambdas สามารถมีพารามิเตอร์จำนวนเท่าใดก็ได้ แต่ไม่ได้อยู่ในวงเล็บปีกกา
  • แลมบ์ดาสามารถมีได้เพียง 1 นิพจน์ในส่วนเนื้อหาของฟังก์ชัน ซึ่งจะถูกส่งกลับตามค่าเริ่มต้น
  • ในระดับไบต์โค้ด ไม่มีความแตกต่างกันมากนักระหว่างวิธีจัดการแลมบ์ดาและฟังก์ชันปกติโดยล่าม
  • Lambdas รองรับ IIFE ผ่านไวยากรณ์นี้: (พารามิเตอร์ lambda: expression)(อาร์กิวเมนต์)
  • โดยทั่วไปแล้ว Lambdas จะถูกใช้กับ Python ในตัวดังต่อไปนี้:
  • ตัวกรอง: ตัวกรอง (พารามิเตอร์แลมบ์ดา: นิพจน์ ลำดับวนซ้ำได้)
  • แผนที่: map (พารามิเตอร์ lambda: expression, iterable-sequences)
  • ลด: ลด (แลมบ์ดา parameter1, parameter2: นิพจน์, ลำดับวนซ้ำได้)
  • อย่าเขียนฟังก์ชัน lambda ที่ซับซ้อนในสภาพแวดล้อมการใช้งานจริง เนื่องจากจะเป็นเรื่องยากสำหรับผู้ดูแลโค้ด

[J5]ฉันได้เพิ่มตารางแล้ว แต่จำเป็นต้องมีคำอธิบายเพื่อทำความเข้าใจความแตกต่าง