ให้ผลผลิตเข้า Python กวดวิชา: Generator & อัตราผลตอบแทนเทียบกับผลตอบแทนตัวอย่าง
ความหมายของ Python ผลผลิต?
คีย์เวิร์ด Yield ใน python ทำงานเหมือนกับการ return เพียงอย่างเดียว
ความแตกต่างคือแทนที่จะส่งคืนค่า มันกลับส่งวัตถุตัวสร้างกลับไปยังผู้เรียก
เมื่อมีการเรียกใช้ฟังก์ชัน และเธรดการดำเนินการพบคำสำคัญ yield ในฟังก์ชัน การดำเนินการของฟังก์ชันจะหยุดที่บรรทัดนั้นและส่งคืนอ็อบเจกต์ตัวสร้างกลับไปยังผู้เรียก
วากยสัมพันธ์
yield expression
Descriptไอออน
Python yield ส่งคืนวัตถุตัวสร้าง Generators เป็นฟังก์ชันพิเศษที่ต้องวนซ้ำเพื่อให้ได้ค่า
คีย์เวิร์ด yield จะแปลงนิพจน์ที่กำหนดให้เป็นฟังก์ชันตัวสร้างที่ส่งคืนอ็อบเจกต์ตัวสร้าง หากต้องการรับค่าของอ็อบเจกต์ จะต้องทำซ้ำเพื่ออ่านค่าที่กำหนดให้กับ yield
ตัวอย่าง: วิธีการให้ผลผลิต
นี่คือตัวอย่างง่ายๆ ของผลตอบแทน ฟังก์ชัน testyield() มีคีย์เวิร์ดที่ให้ผลตอบแทนพร้อมสตริง “Welcome to Guru99 Python สอน“ เมื่อเรียกใช้งานฟังก์ชัน ผลลัพธ์จะถูกพิมพ์ออกมาและจะแสดงวัตถุตัวสร้างแทนค่าจริง
def testyield(): yield "Welcome to Guru99 Python Tutorials" output = testyield() print(output)
Output:
<generator object testyield at 0x00000028265EB9A8>
เอาต์พุตที่กำหนดไว้เป็นวัตถุตัวสร้างซึ่งมีค่าตามที่เรากำหนดให้
แต่เราไม่ได้รับข้อความที่เราต้องให้เพื่อให้ได้ผลลัพธ์!
หากต้องการพิมพ์ข้อความที่กำหนดให้จะต้องทำการวนซ้ำวัตถุตัวสร้างตามที่แสดงในตัวอย่างด้านล่าง:
def testyield(): yield "Welcome to Guru99 Python Tutorials" output = testyield() for i in output: print(i)
Output:
Welcome to Guru99 Python Tutorials
สิ่งที่เป็น Generatorใน Python?
Generators คือฟังก์ชันที่ส่งคืนอ็อบเจกต์ตัวสร้างแบบวนซ้ำได้ ค่าจากอ็อบเจกต์ตัวสร้างจะถูกดึงมาทีละรายการแทนที่จะดึงมาทั้งรายการ ดังนั้นหากต้องการรับค่าจริง คุณสามารถใช้ลูป for โดยใช้เมธอด next() หรือ list()
การใช้ Generator ฟังก์ชัน
คุณสามารถสร้างเครื่องกำเนิดไฟฟ้าได้โดยใช้ฟังก์ชันเครื่องกำเนิดไฟฟ้าและการใช้การแสดงออกของเครื่องกำเนิดไฟฟ้า
ฟังก์ชันตัวสร้างนั้นเหมือนกับฟังก์ชันปกติ ตรงที่ไม่มีค่าส่งคืน แต่จะมีคำสำคัญ yield แทน
หากต้องการสร้างฟังก์ชันตัวสร้าง คุณจะต้องเพิ่มคำสำคัญ yield ตัวอย่างต่อไปนี้จะแสดงวิธีสร้างฟังก์ชันตัวสร้าง
def generator(): yield "H" yield "E" yield "L" yield "L" yield "O" test = generator() for i in test: print(i)
Output:
H E L L O
ความแตกต่างระหว่างฟังก์ชันปกติ v/s Generator ฟังก์ชัน
ให้เรามาทำความเข้าใจว่าฟังก์ชันเครื่องกำเนิดไฟฟ้าแตกต่างจากฟังก์ชันปกติอย่างไร
มี 2 ฟังก์ชัน normal_test() และ generator_test()
ฟังก์ชันทั้งสองนี้ควรจะส่งคืนสตริง "Hello World" กลับมา normal_test() กำลังใช้ return และ generator_test() กำลังใช้ yield
# Normal function def normal_test(): return "Hello World" #Generator function def generator_test(): yield "Hello World" print(normal_test()) #call to normal function print(generator_test()) # call to generator function
Output:
Hello World <generator object generator_test at 0x00000012F2F5BA20>
ผลลัพธ์แสดงให้เห็นว่าเมื่อคุณเรียกใช้ฟังก์ชันปกติ normal_test() ฟังก์ชันนั้นจะส่งกลับสตริง Hello World สำหรับฟังก์ชันตัวสร้างที่มีคำสำคัญ yield ฟังก์ชันนั้นจะส่งกลับสตริง Hello World และไม่ใช่สาย
นี่คือความแตกต่างหลักระหว่างฟังก์ชันตัวสร้างกับฟังก์ชันปกติ หากต้องการรับค่าจากอ็อบเจกต์ตัวสร้าง เราต้องใช้อ็อบเจกต์ภายในลูป for หรือใช้เมธอด next() หรือใช้ list()
print(next(generator_test())) # will output Hello World
ความแตกต่างอีกประการหนึ่งที่ต้องเพิ่มให้กับฟังก์ชันปกติกับฟังก์ชันตัวสร้างคือ เมื่อคุณเรียกฟังก์ชันปกติ การดำเนินการจะเริ่มต้นและหยุดเมื่อถึง กลับ และค่าจะถูกส่งกลับไปยังผู้โทร ดังนั้นเมื่อการดำเนินการเริ่มต้น คุณจะไม่สามารถหยุดฟังก์ชันปกติระหว่างนั้นได้ และจะหยุดเฉพาะเมื่อเจอกับคีย์เวิร์ด return เท่านั้น
แต่ในกรณีของฟังก์ชันตัวสร้าง เมื่อเริ่มดำเนินการเมื่อได้รับผลลัพธ์แรก ฟังก์ชันจะหยุดดำเนินการและส่งวัตถุตัวสร้างกลับคืน คุณสามารถใช้วัตถุตัวสร้างเพื่อรับค่า และหยุดชั่วคราวและดำเนินการต่อตามความต้องการของคุณ
จะอ่านค่าจากเครื่องกำเนิดไฟฟ้าได้อย่างไร
คุณสามารถอ่านค่าจากวัตถุตัวสร้างได้โดยใช้ list(), for-loop และใช้วิธี next()
การใช้ : list()
รายการคือวัตถุที่สามารถวนซ้ำได้ซึ่งมีองค์ประกอบอยู่ในวงเล็บ การใช้ list() กับวัตถุตัวสร้างจะให้ค่าทั้งหมดที่ตัวสร้างถือไว้
def even_numbers(n): for x in range(n): if (x%2==0): yield x num = even_numbers(10) print(list(num))
Output:
[0, 2, 4, 6, 8]
การใช้ : for-in
ในตัวอย่าง มีฟังก์ชัน even_numbers() ที่กำหนดขึ้น ซึ่งจะให้ตัวเลขคู่ทั้งหมดสำหรับ n ที่กำหนดขึ้น การเรียกฟังก์ชัน even_numbers() จะส่งคืนอ็อบเจกต์ตัวสร้าง ซึ่งใช้ภายในลูป for
ตัวอย่าง:
def even_numbers(n): for x in range(n): if (x%2==0): yield x num = even_numbers(10) for i in num: print(i)
Output:
0 2 4 6 8
ใช้ถัดไป()
เมธอด next() จะให้รายการถัดไปในรายการ อาร์เรย์ หรืออ็อบเจ็กต์ เมื่อรายการว่างเปล่า และหากมีการเรียกใช้ next() รายการจะแสดงข้อผิดพลาดพร้อมสัญญาณ stopIteration ข้อผิดพลาดจาก next() นี้บ่งชี้ว่าไม่มีรายการอีกต่อไปในรายการ
def even_numbers(n): for x in range(n): if (x%2==0): yield x num = even_numbers(10) print(next(num)) print(next(num)) print(next(num)) print(next(num)) print(next(num)) print(next(num))
Output:
0 2 4 6 8 Traceback (most recent call last): File "main.py", line 11, in <module> print(next(num)) StopIteration
Generatorเป็นแบบใช้ครั้งเดียว
ในกรณีที่มีเครื่องปั่นไฟ จะสามารถใช้งานได้เพียงครั้งเดียวเท่านั้น หากพยายามใช้งานอีกครั้ง เครื่องจะว่างเปล่า
ตัวอย่างเช่น:
def even_numbers(n): for x in range(n): if (x%2==0): yield x num = even_numbers(10) for i in num: print(i) print("\n") print("Calling the generator again: ", list(num))
Output:
0 2 4 6 8 Calling the generator again: []
ในกรณีที่คุณต้องการนำเอาต์พุตกลับมาใช้อีกครั้ง คุณจะต้องทำการเรียกให้ทำงานอีกครั้ง
ตัวอย่าง: Generators และอัตราผลตอบแทนสำหรับซีรี่ส์ฟีโบนัชชี
ตัวอย่างต่อไปนี้แสดงวิธีการใช้เครื่องกำเนิดไฟฟ้าและผลผลิตใน Python- ตัวอย่างจะสร้างชุด Fibonacci
def getFibonnaciSeries(num): c1, c2 = 0, 1 count = 0 while count < num: yield c1 c3 = c1 + c2 c1 = c2 c2 = c3 count += 1 fin = getFibonnaciSeries(7) print(fin) for i in fin: print(i)
Output:
<generator object getFibonnaciSeries at 0x0000007F39C8BA20> 0 1 1 2 3 5 8
ตัวอย่าง: การเรียกใช้ฟังก์ชันด้วย Yield
ในตัวอย่างนี้เราจะดูวิธีการเรียกใช้ฟังก์ชันด้วย Yield
ตัวอย่างด้านล่างมีฟังก์ชันที่เรียกว่า test() ซึ่งจะคืนค่ากำลังสองของตัวเลขที่กำหนด มีฟังก์ชันอื่นที่เรียกว่า getSquare() ที่ใช้ test() กับคีย์เวิร์ด Yield เอาต์พุตจะให้ค่ากำลังสองสำหรับช่วงตัวเลขที่กำหนด
def test(n): return n*n def getSquare(n): for i in range(n): yield test(i) sq = getSquare(10) for i in sq: print(i)
Output:
0 1 4 9 16 25 36 49 64 81
เมื่อใดควรใช้ Yield แทน Return in Python
Python3 อัตราผลตอบแทน คีย์เวิร์ดส่งคืนตัวสร้างให้แก่ผู้เรียก และการดำเนินการของโค้ดจะเริ่มต้นเมื่อตัวสร้างเกิดการวนซ้ำเท่านั้น
A กลับ ในฟังก์ชันคือการสิ้นสุดการทำงานของฟังก์ชัน และค่าเดียวจะถูกส่งกลับไปยังผู้เรียก
นี่คือสถานการณ์ที่คุณควรใช้ Yield แทน Return
- ใช้ผลตอบแทนแทนการส่งคืนเมื่อขนาดข้อมูลมีขนาดใหญ่
- อัตราผลตอบแทนเป็นตัวเลือกที่ดีที่สุดเมื่อคุณต้องการให้การดำเนินการของคุณเร็วขึ้นบนชุดข้อมูลขนาดใหญ่
- ใช้ Yield เมื่อคุณต้องการคืนค่าชุดใหญ่ให้กับฟังก์ชันการโทร
- อัตราผลตอบแทนเป็นวิธีที่มีประสิทธิภาพในการผลิตข้อมูลที่มีขนาดใหญ่หรือไม่มีที่สิ้นสุด
อัตราผลตอบแทนเทียบกับผลตอบแทน
นี่คือความแตกต่างระหว่าง Yield และ Return
ผล | บริการรถส่ง |
---|---|
Yield จะส่งคืนวัตถุตัวสร้างให้กับผู้เรียก และการดำเนินการของโค้ดจะเริ่มต้นเมื่อตัวสร้างมีการวนซ้ำเท่านั้น | การส่งคืนฟังก์ชันคือการสิ้นสุดการทำงานของฟังก์ชัน และค่าเดียวจะถูกส่งกลับไปยังผู้เรียก |
เมื่อเรียกใช้ฟังก์ชันและพบคำสำคัญ yield การทำงานของฟังก์ชันจะหยุดลง และส่งคืนอ็อบเจกต์ตัวสร้างกลับไปยังผู้เรียก การทำงานของฟังก์ชันจะเริ่มต้นก็ต่อเมื่อดำเนินการอ็อบเจกต์ตัวสร้างแล้วเท่านั้น | เมื่อเรียกใช้ฟังก์ชัน การดำเนินการจะเริ่มต้นขึ้นและค่าจะถูกส่งคืนให้กับผู้เรียกหากมีคีย์เวิร์ด return การส่งคืนภายในฟังก์ชันถือเป็นจุดสิ้นสุดของการดำเนินการฟังก์ชัน |
การแสดงออกของผลผลิต | ส่งคืนนิพจน์ |
ไม่มีการใช้หน่วยความจำเมื่อมีการใช้คำสำคัญผลตอบแทน | หน่วยความจำได้รับการจัดสรรสำหรับค่าที่ส่งคืน |
มีประโยชน์มากหากคุณต้องจัดการกับข้อมูลขนาดใหญ่เนื่องจากไม่ได้ใช้หน่วยความจำ | สะดวกสำหรับขนาดข้อมูลที่เล็กมาก |
ประสิทธิภาพจะดีกว่าหากใช้คำสำคัญผลตอบแทนสำหรับขนาดข้อมูลขนาดใหญ่ | หน่วยความจำจำนวนมากจะถูกใช้หากข้อมูลมีขนาดใหญ่ซึ่งจะขัดขวางประสิทธิภาพ |
เวลาดำเนินการจะเร็วขึ้นในกรณีที่ได้ผลลัพธ์สำหรับข้อมูลขนาดใหญ่ | เวลาดำเนินการที่ใช้จะนานขึ้นเนื่องจากมีการประมวลผลเพิ่มเติมในกรณีที่ข้อมูลของคุณมีขนาดใหญ่ ก็จะทำงานได้ดีกับข้อมูลขนาดเล็ก |
สรุป
- คีย์เวิร์ด yield ใน Python ทำงานเหมือนกับ return โดยมีความแตกต่างเพียงอย่างเดียวคือ แทนที่จะส่งคืนค่า แต่จะส่งฟังก์ชัน generator กลับไปยังตัวเรียกแทน
- ตัวสร้างคือตัววนซ้ำประเภทพิเศษที่เมื่อใช้แล้วจะไม่สามารถใช้ได้อีก ค่าต่างๆ จะไม่ถูกเก็บไว้ในหน่วยความจำและจะพร้อมใช้งานเฉพาะเมื่อเรียกใช้เท่านั้น
- ค่าจากเครื่องกำเนิดไฟฟ้าสามารถอ่านได้โดยใช้เมธอด for-in, list() และ next()
- ความแตกต่างหลักระหว่าง yield และ return ก็คือ yield จะส่งกลับฟังก์ชันตัวสร้างกลับไปยังผู้เรียก และ return จะให้ค่าเดียวแก่ผู้เรียก
- อัตราผลตอบแทนจะไม่เก็บค่าใดๆ ไว้ในหน่วยความจำ และข้อดีคือมีประโยชน์เมื่อข้อมูลมีขนาดใหญ่ เนื่องจากไม่มีค่าใดถูกจัดเก็บไว้ในหน่วยความจำ
- ประสิทธิภาพจะดีกว่าหากใช้คีย์เวิร์ด Yield เพื่อเปรียบเทียบเพื่อให้ได้ข้อมูลขนาดใหญ่