الانتقال إلى المحتوى الرئيسي
الوحدة 6 · الدرس 3 من 423/36 في الدورة~10 min
دروس الوحدة (3/4)

تعبير المولد

تعبير المولد يشبه قائمة الفهم، ولكن مع الأقواس بدلاً من الأقواس المربعة. الفرق دراماتيكي: فهو لا يبني قائمة في الذاكرة، بل ينتج عناصر حسب الطلب، واحد في وقت واحد.

Python
gen = (n * n for n in range(1_000_000))
# istantaneo, memoria costante: nessun calcolo ancora fatto

list_comp = [n * n for n in range(1_000_000)]
# alloca 1M di int in memoria

الكسل (التقييم الكسول)

لا يقوم المولد بأي شيء حتى يطلب شخص ما القيمة التالية:

Python
gen = (n * n for n in range(5))
next(gen)    # 0    (calcolato adesso)
next(gen)    # 1
next(gen)    # 4
# ... e così via, fino a StopIteration

يتم استنفاده: بعد استهلاك جميع العناصر، يصبح فارغًا إلى الأبد. لإعادة استخدامه، يجب عليك إعادة إنشائه.

متى تستخدمه

عندما تقوم بتمرير النتائج إلى دالة تستهلكها بالتسلسل:

Python
total = sum(n * n for n in range(1_000_000))
# nessuna lista intermedia, memoria costante

sum، ​​any، all، max، min، "".join(...) جميعها تقبل المولدات. إذا كانت الوظيفة الخارجية تتطلب فقط أقواس الاستدعاء، فيمكنك ذلك حذف المولد الخاص:

Python
sum((n * n for n in range(10)))    # OK
sum(n * n for n in range(10))      # IDENTICO, più leggibile

any وall: دائرة كهربائية قصيرة

any(...) وall(...) يتوقفان عن التكرار بمجرد حصولهما على الإجابة. مع المولد، لا يتم حساب العناصر التالية حتى.

Python
nums = [1, 2, 3, 4, 5]
any(n > 3 for n in nums)    # True (si ferma a 4)
all(n > 0 for n in nums)    # True
all(n > 2 for n in nums)    # False (si ferma a 1)

النمط: خط أنابيب كسول

Python
righe = (linea.strip() for linea in testo.splitlines())
non_vuote = (r for r in righe if r)
prime_dieci = []
for r in non_vuote:
    prime_dieci.append(r)
    if len(prime_dieci) == 10:
        break

لا توجد قائمة وسيطة، حتى على المدخلات الضخمة.

استهلاك المولدات مع المبلغ، أي، الكل

تعتبر تعبيرات المولدات مثالية للتمرير مباشرة إلى الوظائف التي تستهلك العناصر التكرارية، مثل sum()، أو any()، أو all(). في هذه الحالة، يمكنك حذف الأقواس الخارجية لتعبير المولد، ببساطة كتابة:

Python
squares_sum = sum(x**2 for x in range(10))

وهذا يحافظ على نظافة التعليمات البرمجية الخاصة بك وكفاءة عالية في الذاكرة.

جربه

تمرين#python.m6.l3.e1
المحاولات: 0جارٍ التحميل…

احسب مجموع مربعات الأرقام من 1 إلى 100 (ضمناً) باستخدام تعبير المولد داخل sum(). قم بتعيينه إلى "tot". تقييم "tot".

جارٍ تحميل المحرر…
إظهار التلميح

النطاق (1، 101) يتضمن 100.

الحل متاح بعد 3 من المحاولات

تمرين المراجعة

تمرين#python.m6.l3.e2
المحاولات: 0جارٍ التحميل…

بالنظر إلى `words = ['ciao'، 'mondo'، 'PYTHON'، 'java']`، استخدم Any() مع تعبير منشئ للتحقق مما إذا كانت كلمة واحدة على الأقل كبيرة الحجم (.isupper()). قم بتعيين النتيجة إلى "has_uppercase". تقييم "has_uppercase".

جارٍ تحميل المحرر…
إظهار التلميح

أي (p.isupper () لـ p بالكلمات)

الحل متاح بعد 3 من المحاولات

التحدي الإضافي

تمرين#python.m6.l3.e3
المحاولات: 0جارٍ التحميل…

Use a generator expression passed directly to the `sum()` function to calculate the sum of the squares of all integers from 1 to 100 inclusive. Store the result in `total_sum` and evaluate it.

جارٍ تحميل المحرر…
إظهار التلميح

اكتب Total_sum = sum(x**2 لـ x في النطاق (1, 101)). ليست هناك حاجة للأقواس المزدوجة.

الحل متاح بعد 3 من المحاولات