অসাধারণ পুনরাবৃত্তি এবং তাদের কীভাবে তৈরি করা যায়

আনপ্লেশ-এ জন ম্যাটিচুকের ছবি

সমস্যাটি

মেক স্কুলে অধ্যয়নকালে, আমি সহকর্মীরা ফাংশন লিখতে দেখেছি যা আইটেমের তালিকা তৈরি করে।

s = 'বাচাবক্যাব' পি = 'এ'
ডিফ ফাইন্ড_চার (স্ট্রিং, চরিত্র): সূচকগুলি = তালিকা ()
সূচকের জন্য, গণনা (স্ট্রিং) এ str_char: যদি str_char == অক্ষর: সূচকগুলি appপেন্ড (সূচক)
সূচকগুলি রিটার্ন করুন
মুদ্রণ (সন্ধান_চর (গুলি, পি)) # [1, 2, 4, 7, 8]

এই বাস্তবায়ন কাজ করে, তবে কয়েকটি সমস্যা সৃষ্টি করে:

  • আমরা যদি কেবল প্রথম ফলাফল চাই? আমাদের কি পুরোপুরি নতুন ফাংশন করতে হবে?
  • যদি আমরা ফলাফলটি কেবল একবারে পুনরাবৃত্তি করি, তবে আমাদের প্রতিটি উপাদানকে মেমোরিতে রাখার দরকার নেই?

Iteters এই সমস্যার আদর্শ সমাধান। তারা উত্পাদিত প্রতিটি মানের একটি তালিকা ফেরত না দিয়ে এবং প্রতিটি আইটেম স্বতন্ত্রভাবে ফিরিয়ে দেওয়ার পরিবর্তে "অলস তালিকার" মতো কাজ করে like

ইট্রেটাররা আলস্য মানগুলি ফেরত দেয়। স্মৃতি বাঁচান

সুতরাং আসুন তাদের সম্পর্কে আরও অনুসন্ধান করার জন্য ডুব দেই!

অন্তর্নির্মিত পুনরাবৃত্তি

সর্বাধিক ব্যবহৃত পুনরাবৃত্তি হলেন গণক () এবং জিপ ()। উভয়ই অলসভাবে তাদের সাথে পরবর্তী () এর মানগুলি ফিরিয়ে দেয়।

পরিসর () কোনও পুনরুক্তিকারী নয়, তবে "অলস পুনরাবৃত্তকারী"। - ব্যাখ্যা

আমরা পরিসীমা ()টিকে ইটার () দিয়ে একটি পুনরুক্তিতে রূপান্তর করতে পারি। সুতরাং আমরা আমাদের উদাহরণগুলির জন্য কিছু শিখতে চাই for

আমার_সিটার = ইটার (অঞ্চল (10)) মুদ্রণ (পরবর্তী (আমার_জিটার)) # 0 মুদ্রণ (পরের (আমার_মিটার)) # 1

পরের বার () বলা হয়, আমরা আমাদের পরিসরের পরবর্তী মান পাই। বুদ্ধি ঠিক আছে? যদি আপনি কোনও তালিকার একটি তালিকায় রূপান্তর করতে চান তবে কেবল এটি তালিকা প্রস্তুতকারককে দিন।

আমার_সিটার = ইটার (পরিসর (10)) মুদ্রণ (তালিকা (আমার_মিটার)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

যদি আমরা এই আচরণটির অনুকরণ করি, তবে পুনরাবৃত্তিকারীরা কীভাবে কাজ করে সে সম্পর্কে আমরা আরও জানব।

আমার_সিটার = ইটার (পরিসীমা (10)) আমার_লিস্ট = তালিকা ()
চেষ্টা করুন: সত্য হওয়ার সময়: my_list.append (পরবর্তী (আমার_মিটার)) স্টপআইট্রেশন ব্যতীত: উপস্থিত রয়েছে
মুদ্রণ (আমার_ তালিকা) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

আপনি দেখতে পাচ্ছেন যে আমাদের এটি চেষ্টা করে স্টেটমেন্ট স্টেটমেন্টে আবদ্ধ করতে হয়েছিল। এর কারণ এটিররা ক্লান্ত হয়ে গেলে স্টিপ ইটরেটেশন ট্রিগার করে।

সুতরাং পরের বার যখন আমরা আমাদের ক্লান্ত পরিসীমা পুনরাবৃত্তিকারী বলি তখন আমরা এই ত্রুটিটি দেখতে পাব।

পরবর্তী (আমার_মিটার) # ট্রিগার: স্টপ ইন্টেরেশন

একটি পুনরুক্তি তৈরি করুন

আসুন এমন একটি পুনরুক্তি তৈরির চেষ্টা করি যা তিনটি সাধারণ ধরণের পুনরাবৃত্তির ব্যবহার করে স্টপ আর্গুমেন্টের সাথে পরিসরের মতো আচরণ করে: শ্রেণি, জেনারেটর ফাংশন (ফলন) এবং জেনারেটর এক্সপ্রেশন

দুর্দান্ত

একটি পুনরুক্তি তৈরির পুরানো উপায়টি একটি স্পষ্টভাবে সংজ্ঞায়িত শ্রেণি ছিল। কোনও বস্তুটি পুনরুক্তি হওয়ার জন্য, এটি অবশ্যই___ __ () প্রয়োগ করবে যা নিজেই ফিরে আসে এবং __next __ () যা পরবর্তী মানটি দেয়।

ক্লাস মাই_আরঞ্জ: _কারেন্ট = -1
Def __init __ (স্ব, থামান): স্ব ._স্টপ = স্টপ
Def __iter __ (স্ব): নিজেকে ফিরুন
Def __next __ (স্ব): স্ব ._কালীন + = 1
if self._current> = self._stop: StopIteration ট্রিগার করুন
ফিরে আসুন
আর = আমার_রেঞ্জ (10) মুদ্রণ (তালিকা (আর)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

এটি খুব কঠিন ছিল না, তবে দুর্ভাগ্যক্রমে আমাদের পরবর্তী () এর কলগুলির মধ্যে চলকগুলির দিকে নজর রাখা দরকার। ব্যক্তিগতভাবে, আমি বয়লারপ্লেট পছন্দ করি না বা লুপগুলি সম্পর্কে কীভাবে চিন্তা করি তা পরিবর্তন করি না কারণ এটি কোনও ড্রপ-ইন সমাধান নয়, তাই আমি জেনারেটরগুলি পছন্দ করি

প্রধান সুবিধাটি হ'ল আমরা অতিরিক্ত ফাংশন যুক্ত করতে পারি যা অভ্যন্তরীণ ভেরিয়েবলগুলি পরিবর্তন করে, যেমন। বি। স্টপ, বা নতুন পুনরাবৃত্তি তৈরি করুন।

শ্রেণীর পুনরাবৃত্তিকারীদের অসুবিধা রয়েছে যে তাদের বয়লারপ্লেটের প্রয়োজন। তবে, তাদের অতিরিক্ত ফাংশন থাকতে পারে যা স্থিতি পরিবর্তন করে।

জেনারেটর

পিইপিতে 255 "সাধারণ জেনারেটর" কীওয়ার্ড ফলনের সাথে প্রবর্তিত হয়েছিল।

জেনারেটরগুলি আজ তাদের পুনর্গঠনকারী যা তাদের সহপাঠীর চেয়ে তৈরি করা সহজ।

জেনারেটর ফাংশন

জেনারেটর ফাংশনগুলি এই পিইপি-তে শেষ পর্যন্ত আলোচিত হয়েছিল এবং এগুলি আমার প্রিয় ধরণের পুনরাবৃত্তিকারী। সুতরাং এর সাথে শুরু করা যাক।

Def my_range (থামুন): সূচক = 0
সূচক যখন
আর = আমার_রেঞ্জ (10) মুদ্রণ (তালিকা (আর)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

এই 4 টি লাইন কোডটি কত সুন্দর তা দেখুন? এটিকে শীর্ষে রাখার জন্য এটি আমাদের তালিকা প্রয়োগের চেয়ে কিছুটা ছোট।

জেনারেটর একটি সাধারণ লজিক প্রবাহ সহ ক্লাসের তুলনায় কম বয়লারপ্লেট সহ আইট্রেটারদের কাজ করে।

জেনারেটর ফাংশনগুলি স্বয়ংক্রিয়ভাবে কার্যকর হওয়াতে বাধা দেয় এবং প্রতিবার () বলা হওয়ার পরে নির্দিষ্ট মানটি ফিরিয়ে দেয়। এর অর্থ হ'ল () এ প্রথম কল করা পর্যন্ত কোনও কোড কার্যকর করা হয় না।

এর অর্থ এই যে প্রবাহটি নীচে রয়েছে:

  1. পরের () অর্থ
  2. কোড পরবর্তী ফলন বিবরণী পর্যন্ত কার্যকর করা হয়।
  3. আয়ের অধিকারের মানটি ফেরত দেওয়া হয়।
  4. ফাঁসি কার্যকর হবে।
  5. কোডের শেষ লাইন পৌঁছানো পর্যন্ত প্রতিটি পরবর্তী () কলের জন্য 1–5 পুনরাবৃত্তি।
  6. স্টপ ইন্টেরেশন ট্রিগার করা হয়।

জেনারেটরের ক্রিয়াকলাপগুলির সাথে, আপনি কীওয়ার্ড থেকে ফলনটিও ব্যবহার করতে পারেন, যা ভবিষ্যতে পরবর্তী () কে পুনরাবৃত্তযোগ্য অবসন্ন না হওয়া অবধি আরেকটি পুনরাবৃত্তে কল করে।

Def উত্পাদিত_আরঙ্গ (): আমার_আরঞ্জের ফলন (10)
মুদ্রণ (তালিকা (উত্পাদিত_আরঙ্গ ()) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

এটি বিশেষ জটিল উদাহরণ ছিল না। তবে আপনি এটি পুনরাবৃত্তভাবে করতে পারেন!

Def my_range_recursive (থামুন, বর্তমান = 0): যদি বর্তমান> = থামান: ফিরে আসুন
আমার_রঞ্জন_প্রতিক্রিয়া থেকে প্রবাহিত স্ট্রিম উপার্জন (স্টপ, বর্তমান +1)
আর = আমার_আরঞ্জি_আরেকসিভ (10) মুদ্রণ (তালিকা (আর)) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

জেনারেটর এক্সপ্রেশন

জেনারেটর এক্সপ্রেশন আমাদের ওয়ান-লাইনার হিসাবে পুনরুক্তি তৈরি করতে দেয়। যখন কোনও বাহ্যিক কার্যকারিতা প্রয়োজন হয় না তখন এগুলি ভাল। দুর্ভাগ্যক্রমে, আমরা একটি এক্সপ্রেশন দিয়ে অন্য একটি মাইআরঞ্জ তৈরি করতে পারি না, তবে আমরা আমাদের শেষ মাইআরেঞ্জ ফাংশনের মতো পুনরাবৃত্তিকে হেরফের করতে পারি।

my_doubled_range_10 = (মাই_রেঞ্জে এক্স এর জন্য x * 2 (10)) মুদ্রণ (তালিকা (আমার_দ্বৈত_আরঞ্জ_০)) # 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

এটি সম্পর্কে দুর্দান্ত জিনিসটি এটি নিম্নলিখিতটি করে:

  1. তালিকায়, my_doubled_range_10 পরবর্তী মানের জন্য জিজ্ঞাসা করা হয়।
  2. my_doubled_range_10 পরের মানটির জন্য আমার_আরঞ্জকে জিজ্ঞাসা করে।
  3. my_doubled_range_10 আমার_রেঞ্জের মান 2 দ্বারা গুণিত করে।
  4. তালিকাটি নিজের মধ্যে মান সংযোজন করে।
  5. আমার_দোবल्ड_আরঞ্জ_10 স্টিপ ইন্টেরেশন ট্রিগার না হওয়া পর্যন্ত 1-5 পুনরাবৃত্তি করুন, যখন আমার_আরঞ্জ এটি করে তখন কী ঘটে।
  6. আমার_দৌল_আরেঞ্জ দ্বারা প্রত্যাবর্তিত প্রতিটি মান দিয়ে তালিকাটি ফিরে আসে।

এমনকি আমরা জেনারেটর এক্সপ্রেশন দিয়ে ফিল্টার করতে পারি!

my_even_range_10 = (আমার x_ x (10) এ x এর জন্য x, যদি x% 2 == 0) মুদ্রণ (তালিকা (my_even_range_10)) # # [0, 2, 4, 6, 8]

এটি পূর্বেরটির সাথে খুব মিল, কেবলমাত্র_আমার_আর_আরঞ্জ_০ কেবলমাত্র শর্তগুলির সাথে মেলে এমন মানগুলি প্রদান করে যা কেবলমাত্র [0, 10] এর মধ্যে রয়েছে।

এদিকে, আমরা কেবল একটি তালিকা তৈরি করছি কারণ আমরা এটি সাজিয়েছি।

সুবিধা

উৎস

জেনারেটরগুলি পুনরাবৃত্তকারী হওয়ায় পুনরুক্তিগুলি পুনরাবৃত্ত হয় এবং পুনরুক্তিগুলি আলস্য মানগুলি দেয়। এর অর্থ হ'ল এই জ্ঞানের সাহায্যে আমরা এমন অবজেক্ট তৈরি করতে পারি যা কেবলমাত্র যখন আমরা তাদের কাছে জিজ্ঞাসা করি এবং আমরা কতগুলি চাই সেগুলি কেবল আমাদের অবজেক্ট দেয়।

এর অর্থ আমরা জেনারেটরগুলিকে ফাংশনে রূপান্তর করতে পারি যা একে অপরকে হ্রাস করে।

মুদ্রণ (যোগফল (আমার_রেঞ্জ (10)) # 45 45

এই উপায়ে মোট গণনা করা যদি আপনি কেবল এগুলি যুক্ত করেন এবং তারপরে এগুলি বাতিল করেন তবে কোনও তালিকা তৈরি করা এড়ানো যায়।

আমরা একটি জেনারেটর ফাংশন দিয়ে আরও ভাল পেতে খুব প্রথম উদাহরণটি আবার লিখতে পারি!

s = 'বাচাবক্যাব' পি = 'এ'
ডিফ ফাইন্ড_চার (স্ট্রিং, চরিত্র): সূচকের জন্য, গণনা (স্ট্রিং) এ str_char: যদি str_char == অক্ষর: ফলন সূচক
মুদ্রণ (তালিকা (সন্ধান_চর (গুলি, পি))) # [1, 2, 4, 7, 8]

এখনই একটি সুস্পষ্ট সুবিধা নাও হতে পারে, তবে আসুন আমার প্রথম প্রশ্নে এগিয়ে যাই, "আমরা যদি কেবল প্রথম ফলাফলটি চাই? আমাদের কি পুরোপুরি নতুন ভূমিকা নিতে হবে? "

একটি জেনারেটর ফাংশন সহ, আমাদের ততটা যুক্তি আবার লিখতে হবে না।
মুদ্রণ (পরবর্তী (সন্ধান_চর (গুলি, পি))) # 1

এখন আমরা আমাদের মূল সমাধানটি দিয়েছি তালিকার প্রথম মান পেতে পারি। যাইহোক, এইভাবে আমরা কেবল প্রথম ম্যাচটি পাই এবং তালিকাটি পুনরাবৃত্তি বন্ধ করি। জেনারেটরটি পরে ফেলে দেওয়া হয় এবং অন্য কিছুই তৈরি হয় না। স্মৃতি বিপুল পরিমাণে সংরক্ষণ করুন।

উপসংহার

আপনি যদি কখনও কোনও ফাংশন তৈরি করেন তবে এ জাতীয় তালিকার মানগুলি যুক্ত হয়ে যায়।

Def foo (বার): মান = []
বারে এক্সের জন্য: # কিছু যুক্তিযুক্ত মান appপেনড (এক্স)
মানগুলি ফেরান

কোনও শ্রেণি, জেনারেটর ফাংশন, বা জেনারেটর এক্সপ্রেশন সহ একটি পুনরাবৃত্তি ফেরানোর বিষয়টি বিবেচনা করুন:

Def foo (বার): বারে x এর জন্য: # কিছু যুক্তি উত্পন্ন x

সংস্থান এবং উত্স

পিইপি

  • জেনারেটর
  • জেনারেটর এক্সপ্রেশন PEP
  • পিইপি থেকে আয়

নিবন্ধ এবং বিষয়গুলি

  • Iteilers
  • Iteable বনাম Iterator
  • জেনারেটর ডকুমেন্টেশন
  • ইটারেটর বনাম জেনারেটর
  • জেনারেটর এক্সপ্রেশন বনাম ফাংশন
  • পুনঃনির্মাণ জেনারেটর

সংজ্ঞা

  • পুনরাবৃত্তিযোগ্য
  • আইট্রেটার
  • জেনারেটর
  • জেনারেটর পুনরুক্তি
  • জেনারেটর এক্সপ্রেশন

মূলত https://blog.dacio.dev/2019/05/03/python-iteators-and-generators/ এ প্রকাশিত।