ความเข้าใจของเครื่องกำเนิดไฟฟ้าทำงานอย่างไร?


96

ความเข้าใจของเครื่องกำเนิดไฟฟ้าทำอะไร? มันทำงานอย่างไร? ฉันไม่พบบทแนะนำเกี่ยวกับเรื่องนี้


2
เพื่อความชัดเจนชื่อภาษาสำหรับสิ่งเหล่านี้คือนิพจน์ตัวสร้างไม่ใช่ความเข้าใจของตัวสร้าง
ShadowRanger

2
@ShadowRanger มีการอภิปรายเกี่ยวกับรายชื่ออีเมล Python-dev ในเดือนกรกฎาคมปี 2018 เรื่อง "ไวยากรณ์การตั้งชื่อเพื่อความเข้าใจ"ซึ่งมีข้อตกลงเบื้องต้น แต่เป็นเอกฉันท์ในการเรียกสิ่งเหล่านี้ว่า "ความเข้าใจของเครื่องกำเนิดไฟฟ้า" เพื่อความสอดคล้อง
แอรอนฮอลล์

คำตอบ:


149

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

>>> my_list = [1, 3, 5, 9, 2, 6]
>>> filtered_list = [item for item in my_list if item > 3]
>>> print(filtered_list)
[5, 9, 6]
>>> len(filtered_list)
3
>>> # compare to generator expression
... 
>>> filtered_gen = (item for item in my_list if item > 3)
>>> print(filtered_gen)  # notice it's a generator object
<generator object <genexpr> at 0x7f2ad75f89e0>
>>> len(filtered_gen) # So technically, it has no length
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'generator' has no len()
>>> # We extract each item out individually. We'll do it manually first.
... 
>>> next(filtered_gen)
5
>>> next(filtered_gen)
9
>>> next(filtered_gen)
6
>>> next(filtered_gen) # Should be all out of items and give an error
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> # Yup, the generator is spent. No values for you!
... 
>>> # Let's prove it gives the same results as our list comprehension
... 
>>> filtered_gen = (item for item in my_list if item > 3)
>>> gen_to_list = list(filtered_gen)
>>> print(gen_to_list)
[5, 9, 6]
>>> filtered_list == gen_to_list
True
>>> 

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


4
คำถามเดียวที่นี่ ฉันใช้ next (gen_name) เพื่อรับผลลัพธ์และมันใช้งานได้ใน Python 3 มีสถานการณ์เฉพาะที่เราต้องใช้ __next __ () หรือไม่
Ankit Vashistha

4
@AnkitVashistha ไม่ใช้next(...)แทน.__next__()ใน Python 3 เสมอ
Todd Sewell

2
@gotgenes @AnkitVashistha If you need more than one value, you can also use a generator expression and grab a few at a time. คุณช่วยยกตัวอย่างเกี่ยวกับการใช้งานนี้ได้ไหม ขอบคุณ.
LittleZero

21

ความเข้าใจของเครื่องกำเนิดไฟฟ้าเป็นเวอร์ชันที่ขี้เกียจของความเข้าใจในรายการ

มันเหมือนกับการทำความเข้าใจรายการยกเว้นว่าจะส่งคืนตัววนซ้ำแทนที่จะเป็นรายการเช่นอ็อบเจ็กต์ที่มีเมธอด next () ที่จะให้องค์ประกอบถัดไป

ถ้าคุณไม่คุ้นเคยกับ comprehensions รายการดูที่นี่และเครื่องกำเนิดไฟฟ้าดูที่นี่


4

ความเข้าใจของรายการ / ตัวสร้างคือโครงสร้างที่คุณสามารถใช้เพื่อสร้างรายการ / ตัวสร้างใหม่จากรายการที่มีอยู่

สมมติว่าคุณต้องการสร้างรายการกำลังสองของแต่ละหมายเลขตั้งแต่ 1 ถึง 10 คุณสามารถทำได้ใน Python:

>>> [x**2 for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

ที่นี่range(1,11)สร้างรายการ[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]แต่rangeฟังก์ชั่นไม่ใช่ตัวสร้างก่อน Python 3.0 ดังนั้นโครงสร้างที่ฉันใช้คือการทำความเข้าใจรายการ

หากฉันต้องการสร้างเครื่องกำเนิดไฟฟ้าที่ทำสิ่งเดียวกันฉันสามารถทำได้ดังนี้:

>>> (x**2 for x in xrange(1,11))
<generator object at 0x7f0a79273488>

อย่างไรก็ตามใน Python 3 rangeเป็นตัวสร้างดังนั้นผลลัพธ์จึงขึ้นอยู่กับไวยากรณ์ที่คุณใช้เท่านั้น (วงเล็บเหลี่ยมหรือวงเล็บกลม)


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

สามารถเขียนใหม่ให้ชัดเจนขึ้นได้หรือไม่? ฉันเข้าใจในสิ่งที่คุณกำลังพูด แต่อย่างที่พลวงพูดดูเหมือนว่าคุณกำลังพูดอย่างอื่น (และสิ่งที่ดูเหมือนว่าคุณพูดผิด)
Lyndon White

4

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

def allEvens( L ):
    for number in L:
        if number % 2 is 0:
            yield number

evens = allEvens( yourList )

คุณสามารถบรรลุผลลัพธ์เดียวกันด้วยนิพจน์ความเข้าใจของเครื่องกำเนิดไฟฟ้านี้:

evens = ( number for number in your_list if number % 2 == 0 )

ในทั้งสองกรณีเมื่อคุณเรียกคุณจะได้รับจำนวนคู่ต่อไปในnext(evens)your_list


1

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

ในระยะสั้นโดยใช้ความเข้าใจของเครื่องกำเนิดไฟฟ้าคุณสามารถสร้างเคอร์เซอร์ใน python ได้อย่างง่ายดาย



0

เครื่องกำเนิดไฟฟ้าเหมือนกับรายการเท่านั้นความแตกต่างเล็กน้อยคือในรายการเราได้รับหมายเลขหรือรายการที่ต้องการทั้งหมดในรายการ แต่ในเครื่องกำเนิดไฟฟ้าหมายเลขที่ต้องการจะได้รับทีละรายการ ดังนั้นในการรับไอเทมที่ต้องการเราต้องใช้ for loop เพื่อรับไอเทมที่ต้องการทั้งหมด

#to get all the even numbers in given range
 
def allevens(n):
    for x in range(2,n):
        if x%2==0:
            yield x

for x in allevens(10)
print(x)

#output
2
4
6
8
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.