জেনারেটরগুলি অলস-মূল্যায়ন করছে তাই return
বা yield
আপনার কোডটি ডিবাগ করার সময় বা কোনও ব্যতিক্রম ছুঁড়ে ফেলা হলে অন্যরকম আচরণ করবে।
আপনার সাথে return
যে কোনও ব্যতিক্রম ঘটে সে generator
সম্পর্কে কিছুই জানতে পারবেন না generate_all
, কারণ generator
সত্যিকার অর্থে মৃত্যুদন্ড কার্যকর করা হলে আপনি ইতিমধ্যে generate_all
ফাংশনটি রেখে গেছেন । সঙ্গে yield
সেখানে এটা করতে হবে generate_all
ট্রেসব্যাক হবে।
def generator(some_list):
for i in some_list:
raise Exception('exception happened :-)')
yield i
def generate_all():
some_list = [1,2,3]
return generator(some_list)
for item in generate_all():
...
Exception Traceback (most recent call last)
<ipython-input-3-b19085eab3e1> in <module>
8 return generator(some_list)
9
---> 10 for item in generate_all():
11 ...
<ipython-input-3-b19085eab3e1> in generator(some_list)
1 def generator(some_list):
2 for i in some_list:
----> 3 raise Exception('exception happened :-)')
4 yield i
5
Exception: exception happened :-)
এবং যদি এটি ব্যবহার করে yield from
:
def generate_all():
some_list = [1,2,3]
yield from generator(some_list)
for item in generate_all():
...
Exception Traceback (most recent call last)
<ipython-input-4-be322887df35> in <module>
8 yield from generator(some_list)
9
---> 10 for item in generate_all():
11 ...
<ipython-input-4-be322887df35> in generate_all()
6 def generate_all():
7 some_list = [1,2,3]
----> 8 yield from generator(some_list)
9
10 for item in generate_all():
<ipython-input-4-be322887df35> in generator(some_list)
1 def generator(some_list):
2 for i in some_list:
----> 3 raise Exception('exception happened :-)')
4 yield i
5
Exception: exception happened :-)
তবে এটি পারফরম্যান্সের ব্যয়ে আসে। অতিরিক্ত জেনারেটর স্তরের কিছু ওভারহেড থাকে। সুতরাং return
সাধারণত yield from ...
(বা for item in ...: yield item
) থেকে কিছুটা দ্রুত হবে । বেশিরভাগ ক্ষেত্রে এটি খুব বেশি গুরুত্ব দেয় না, কারণ আপনি জেনারেটরে যা কিছু করেন তা সাধারণত রান-টাইমকে প্রাধান্য দেয় যাতে অতিরিক্ত স্তরটি লক্ষণীয় না হয়।
তবে yield
কিছু অতিরিক্ত সুবিধা রয়েছে: আপনি একক পুনরাবৃত্তির মধ্যে সীমাবদ্ধ নন, আপনি সহজেই অতিরিক্ত আইটেমও উত্পাদন করতে পারবেন:
def generator(some_list):
for i in some_list:
yield i
def generate_all():
some_list = [1,2,3]
yield 'start'
yield from generator(some_list)
yield 'end'
for item in generate_all():
print(item)
start
1
2
3
end
আপনার ক্ষেত্রে ক্রিয়াকলাপগুলি বেশ সহজ এবং এটির জন্য একাধিক ফাংশন তৈরি করা এমনকি প্রয়োজনীয় কিনা আমি জানি না, map
তার পরিবর্তে একটি বিল্ট-ইন বা জেনারেটর এক্সপ্রেশনটি সহজেই ব্যবহার করতে পারে :
map(do_something, get_the_list()) # map
(do_something(i) for i in get_the_list()) # generator expression
উভয় ব্যবহারের জন্য অভিন্ন হওয়া উচিত (ব্যতিক্রম ঘটলে কিছু পার্থক্য বাদে)। এবং যদি তাদের আরও বর্ণনামূলক নামের প্রয়োজন হয় তবে আপনি তাদের এখনও একটি ফাংশনে মুড়িয়ে রাখতে পারেন।
এমন একাধিক সহায়ক রয়েছে যা পূর্বে অন্তর্নির্মিত পুনরাবৃত্তির উপর খুব সাধারণ ক্রিয়াকলাপগুলিকে আবৃত করে রাখে এবং আরও অন্তর্নির্মিত itertools
মডিউলটিতে পাওয়া যায় । এই জাতীয় সহজ ক্ষেত্রে আমি কেবল এগুলি অবলম্বন করব এবং কেবলমাত্র তুচ্ছ মামলার জন্য নিজের জেনারেটর লিখি।
তবে আমি ধরে নিলাম আপনার আসল কোডটি আরও জটিল তাই এটি প্রযোজ্য নাও হতে পারে তবে আমি ভেবেছিলাম বিকল্পগুলির উল্লেখ না করে এটি একটি সম্পূর্ণ উত্তর হবে না।