মূল কন্টেন্টে যান
মডিউল 6 · 3-এর পাঠ 4কোর্সে 23/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 সহ জেনারেটর গ্রাস করছে

জেনারেটর এক্সপ্রেশনগুলি sum(), any(), বা all() এর মতো পুনরাবৃত্তিযোগ্য ফাংশনগুলিতে সরাসরি পাস করার জন্য উপযুক্ত। এই ক্ষেত্রে, আপনি জেনারেটর এক্সপ্রেশনের বাইরের বন্ধনীগুলি বাদ দিতে পারেন, কেবল লিখুন:

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

এটি আপনার কোড পরিষ্কার এবং উচ্চ মেমরি-দক্ষ রাখে।

চেষ্টা করে দেখুন

ব্যায়াম#python.m6.l3.e1
প্রচেষ্টা: 0লোড হচ্ছে...

sum() এর ভিতরে একটি জেনারেটর এক্সপ্রেশন ব্যবহার করে 1 থেকে 100 (অন্তর্ভুক্ত) সংখ্যার বর্গক্ষেত্রের যোগফল গণনা করুন। এটিকে 'টোট'-এ বরাদ্দ করুন। `tot` মূল্যায়ন করুন।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

পরিসীমা (1, 101) 100টি অন্তর্ভুক্ত করে।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

ব্যায়াম পর্যালোচনা করুন

ব্যায়াম#python.m6.l3.e2
প্রচেষ্টা: 0লোড হচ্ছে...

প্রদত্ত `শব্দ = ['ciao', 'mondo', 'PYTHON', 'java']`, অন্তত একটি শব্দ বড় হাতের (.isupper()) কিনা তা পরীক্ষা করতে একটি জেনারেটর এক্সপ্রেশন সহ যেকোনো() ব্যবহার করুন। ফলাফলটি `has_uppercase`-এ বরাদ্দ করুন। `has_uppercase` মূল্যায়ন করুন।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

শব্দে p এর জন্য any(p.isupper())

সমাধান 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 = যোগফল(x**2 এর জন্য x পরিসরে (1, 101))। ডবল বন্ধনী প্রয়োজন নেই.

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ