পাইথন পুনরুক্তিগুলিতে নেক্সট?


উত্তর:


106

না, এমন কোনও পদ্ধতি নেই। পুনরাবৃত্তির শেষটি ব্যতিক্রম দ্বারা নির্দেশিত হয়। ডকুমেন্টেশন দেখুন ।


71
"অনুমতি চেয়ে ক্ষমা চাওয়া সহজ।"

118
"অনুমতি চেয়ে ক্ষমার জন্য জিজ্ঞাসা করা সহজ" ": পুনরাবৃত্তকারীটির পরবর্তী উপাদান রয়েছে কিনা তা যাচাই করা হচ্ছে না। এমন পরিস্থিতিতে রয়েছে যেগুলি আপনি গ্রহণ না করে পরবর্তী উপাদানটির অস্তিত্বের জন্য পরীক্ষা করতে চান। আমি unnext()কল করার মাধ্যমে এটি উপস্থিত রয়েছে কিনা তা যাচাই করে নেওয়ার পরে যদি প্রথম উপাদানটিকে পিছনে রাখার কোনও পদ্ধতি ছিল তবে আমি চেষ্টা ধরার সমাধানটি গ্রহণ করব next()
জর্জিও

15
@ জর্জিও, কোড জেনারেট না করে অন্য উপাদান উপস্থিত রয়েছে কিনা তা জানার উপায় নেই (জেনারেটর কার্যকর হবে কিনা তা আপনি জানেন yieldনা)। এটি অবশ্যই কোনও অ্যাডাপ্টার লিখতে অসুবিধা নয় যা ফলাফল সংরক্ষণ করে next()এবং সরবরাহ করে has_next()এবং move_next()
অবাক

5
একই ধারণাটি hasNext()পদ্ধতিটি প্রয়োগ করতে (উত্পাদন, ক্যাশে এবং সাফল্যে সত্য প্রত্যাবর্তন, বা ব্যর্থতায় মিথ্যা প্রত্যাবর্তনের জন্য) ব্যবহার করা যেতে পারে । তারপরে hasNext()এবং উভয়ই next()একটি সাধারণ অন্তর্নিহিত getNext()পদ্ধতি এবং ক্যাশেড আইটেমের উপর নির্ভর করবে । আমি সত্যিই দেখতে পাই না কেন next()স্ট্যান্ডার্ড লাইব্রেরিতে না থাকা উচিত যদি এটি সরবরাহ করে এমন একটি অ্যাডাপ্টার কার্যকর করতে এত সহজ হয়।
জর্জিও 21

3
@ লার্শ: আপনার অর্থ উদাহরণস্বরূপ এমন একটি পুনরাবৃত্তি যা কোনও ফাইল থেকে পড়া যা এটি থেকে পড়ার সময় পরিবর্তন করা যায়? আমি সম্মত হই যে এটি কোনও সমস্যা হতে পারে (যা কোনও অনুমানক পাইথন গ্রন্থাগার নয়, কোনও গ্রন্থাগার সরবরাহ next()এবং hasNext()পদ্ধতিকে প্রভাবিত করে )। সুতরাং হ্যাঁ, next()এবং hasNext()স্ট্রিমের বিষয়বস্তুটি স্ক্যান করার সময় উপাদানগুলি কখন পড়ার উপর নির্ভর করে trick
জর্জিও

239

StopIterationব্যবহার করে একটি বিকল্প আছে next(iterator, default_value)

এক্সপামলের জন্য:

>>> a = iter('hi')
>>> print next(a, None)
h
>>> print next(a, None)
i
>>> print next(a, None)
None

সুতরাং আপনি Noneযদি ব্যতিক্রম উপায় না চান তবে আপনি পুনরাবৃত্তির শেষের জন্য বা অন্যান্য পূর্বনির্ধারিত মান সনাক্ত করতে পারেন ।


70
আপনি যদি কোনওটিকে "সেন্ডিনেল" হিসাবে ব্যবহার করেন না, আপনি অবশ্যই নিশ্চিত হন যে আপনার পুনরাবৃত্তির কোনও নোন নেই। আপনার কাছে যেত না sentinel = object()এবং next(iterator, sentinel)এবং পরীক্ষা is
সাম বুসালিস

1
স্যাম্বোসালিস অনুসরণ করে আমি বরং বিল্ট-ইন unittest.mock.sentinelঅবজেক্টটি ব্যবহার করব যা আপনাকে স্পষ্ট করে লিখতে next(a, sentinel.END_OF_ITERATION)এবং তারপরেif next(...) == sentinel.END_OF_ITERATION
ক্লিমেন্টওয়াল্টার

এটি ব্যতিক্রমের তুলনায় প্রাকৃতিক
দ্যাটদিনহোকোক

সমস্যাটি হ'ল, এইভাবে, আপনি পুনরুক্তিকারী থেকে পরবর্তী মানটিও গণনা করুন। জাভায় হ্যাসনেক্সট পরবর্তী মানটি গ্রাস করে না।
অ্যালান ফ্রানজোনি

39

আপনি কি সত্যিই যদি প্রয়োজন একটি has-nextকার্যকারিতা (কারণ আপনি শুধু নিখুঁতভাবে জাভা একটি রেফারেন্স বাস্তবায়ন থেকে একটি অ্যালগরিদম নকলনবিসি করছি, বলুন বা কারণ আপনি একটি প্রোটোটাইপ যে লেখার হবে সহজে জাভা প্রতিলিপি করা এটি সমাপ্ত হলে প্রয়োজন), এটা করা খুবই সহজ এটি একটি সামান্য মোড়কের ক্লাসের সাথে গ্রহণ করুন। উদাহরণ স্বরূপ:

class hn_wrapper(object):
  def __init__(self, it):
    self.it = iter(it)
    self._hasnext = None
  def __iter__(self): return self
  def next(self):
    if self._hasnext:
      result = self._thenext
    else:
      result = next(self.it)
    self._hasnext = None
    return result
  def hasnext(self):
    if self._hasnext is None:
      try: self._thenext = next(self.it)
      except StopIteration: self._hasnext = False
      else: self._hasnext = True
    return self._hasnext

এখন যেমন কিছু

x = hn_wrapper('ciao')
while x.hasnext(): print next(x)

নিঃসরণ করে

c
i
a
o

প্রয়োজনীয়.

মনে রাখবেন যে next(sel.it)বিল্ট-ইন হিসাবে ব্যবহারের জন্য পাইথন ২.6 বা তারও বেশি প্রয়োজন; যদি আপনি পাইথনের একটি পুরানো সংস্করণ ব্যবহার করেন তবে self.it.next()পরিবর্তে (এবং একইভাবে next(x)উদাহরণ ব্যবহারের জন্য) ব্যবহার করুন। [[আপনি সম্ভবত যুক্তিযুক্তভাবে এই নোটটি অপ্রয়োজনীয় হিসাবে ভাবতে পারেন, যেহেতু পাইথন ২.6 এখন প্রায় এক বছরেরও বেশি সময় ধরে চলেছে - তবে প্রায়শই আমি যখন সাড়াতে পাইথন ২.6 বৈশিষ্ট্য ব্যবহার করি না তখনই কিছু মন্তব্যকারী বা অন্যান্য মনে করেন যে দায়িত্বটি বাধ্যবাধকতা রয়েছে) তারা যে হয় 2.6 বৈশিষ্ট্য, এইভাবে আমি একবার ;-)]] এর জন্য এই ধরনের মন্তব্য আটকানোর চেষ্টা করছি


9
"জাভাতে রেফারেন্স বাস্তবায়ন থেকে বিশ্বস্তভাবে একটি অ্যালগরিদম প্রতিলিপি করা" একটি has_nextপদ্ধতির প্রয়োজন সবচেয়ে খারাপ কারণ । পাইথনের নকশায় বলা হয়েছে, filterকোনও অ্যারে প্রদত্ত প্রাকটিকের সাথে মিল রেখে কোনও উপাদান রয়েছে কিনা তা পরীক্ষা করে দেখতে অসম্ভব করে তোলে । পাইথন সম্প্রদায়ের অহংকার ও সংক্ষিপ্ততা বিস্ময়কর।
জোনাথন


আমি পাইথন 3 এর সাথে আছি এবং এই কোডটি আমাকে দেয়TypeError: iter() returned non-iterator
madtyn

1
@ জোনাথান ক্যাসেট নিশ্চিত না যে আমি অনুসরণ করি। পাইথনে, আপনি সাধারণত ব্যবহার করতে পারেন mapএবং anyতার পরিবর্তে filter, তবে আপনি SENTINEL = object(); next(filter(predicate, arr), SENTINEL) is not SENTINELএকটি ব্যবহার করতে বা ভুলে যেতে পারেন SENTINELএবং কেবল ব্যবহার করতে try: exceptএবং ধরতে পারেন StopIteration
juanpa.arrivillaga

13

স্টপআইটারেশনের সমস্ত উল্লেখের পাশাপাশি পাইথন "ফর" লুপটি আপনি যা চান তা কেবলভাবে করে:

>>> it = iter("hello")
>>> for i in it:
...     print i
...
h
e
l
l
o

7

যে কোনও পুনরাবৃত্তকারী অবজেক্ট থেকে __leight_hint __ () পদ্ধতিটি ব্যবহার করে দেখুন:

iter(...).__length_hint__() > 0

5
আমি সর্বদা ভাবতাম যে পৃথিবীতে অজগরটিতে এই সমস্ত __ xxx __ পদ্ধতি রয়েছে কেন? তারা দেখতে খুব কুরুচিপূর্ণ।
এমপি।

6
আইনী প্রশ্ন! সাধারণত এটি এমন পদ্ধতিগুলির সিনট্যাক্স যা কোনও বিল্টিন ফাংশন দ্বারা প্রকাশ করা হয় (যেমন লেন, লেনকে কল করছে ) calling দৈর্ঘ্য ইঙ্গিতের জন্য এই ধরনের বিল্টিন ফাংশন বিদ্যমান নেই, তবে এটি আসলে একটি মুলতুবি প্রস্তাব (PEP424)।
ফুলমিকোটন

1
@mP। এই ফাংশনগুলি আছে, কারণ তাদের কখনও কখনও প্রয়োজন হয়। তারা ইচ্ছাকৃতভাবে কুৎসিত, কারণ এগুলি শেষ অবলম্বনের পদ্ধতি হিসাবে বিবেচিত: আপনি যদি এগুলি ব্যবহার করেন তবে আপনি জানেন যে আপনি অ-পাইথোনিক এবং সম্ভাব্য বিপজ্জনক কিছু করেন (এটি কোনও সময়ে কাজ করাও বন্ধ করে দিতে পারে)।
আরনে বাবেনহাউসারহিড

লাইক __init__এবং __main__? ইমো, আপনি এটিকে ন্যায্য প্রমাণ করার চেষ্টা করুন না কেন এটি কিছুটা গণ্ডগোল।
ব্যবহারকারী 1363990

5

hasNextকিছুটা StopIterationব্যতিক্রম যেমন অনুবাদ করে :

>>> it = iter("hello")
>>> it.next()
'h'
>>> it.next()
'e'
>>> it.next()
'l'
>>> it.next()
'l'
>>> it.next()
'o'
>>> it.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

4

আপনি teeপুনরাবৃত্তকারী ব্যবহার করে, itertools.teeএবং StopIterationটিড পুনরুক্তিকারীর জন্য পরীক্ষা করতে পারেন ।


3

না। সর্বাধিক অনুরূপ ধারণাটি সম্ভবত একটি স্টপআইটিরেশন ব্যতিক্রম।


10
পাইথন নিয়ন্ত্রণ প্রবাহে ব্যতিক্রমগুলি কী ব্যবহার করে? বেশ নাফ্ট লাগছে।
এমপি।

5
ডান: ব্যতিক্রমগুলি ত্রুটিগুলি পরিচালনা করতে ব্যবহার করা উচিত, নিয়ন্ত্রণের সাধারণ প্রবাহকে সংজ্ঞায়িত করতে নয়।
জর্জিও


1

ব্যবহারের ক্ষেত্রে যা আমাকে এটি অনুসন্ধান করতে পরিচালিত করে তা নীচে রয়েছে

def setfrom(self,f):
    """Set from iterable f"""
    fi = iter(f)
    for i in range(self.n):
        try:
            x = next(fi)
        except StopIteration:
            fi = iter(f)
            x = next(fi)
        self.a[i] = x 

যেখানে সংক্ষিপ্তসার () পাওয়া যায়, সেখানে কেউ করতে পারে

def setfrom(self,f):
    """Set from iterable f"""
    fi = iter(f)
    for i in range(self.n):
        if not hasnext(fi):
            fi = iter(f) # restart
        self.a[i] = next(fi)

আমার কাছে যা পরিষ্কার। স্পষ্টতই আপনি ইউটিলিটি ক্লাসগুলি সংজ্ঞায়িত করে ইস্যুগুলি নিয়ে কাজ করতে পারেন, তবে তারপরে যা ঘটে তা হ'ল আপনার কুড়ি দিয়ে প্রতিটি বিশ-মতামত প্রায় সমতুল্য ওয়ার্কারআউন্ডের বিস্তার এবং আপনি যদি আলাদা ওয়ার্কআউন্ড ব্যবহার করে এমন কোডটি পুনরায় ব্যবহার করতে চান, তবে আপনাকে অবশ্যই আপনার একক অ্যাপ্লিকেশনটিতে একাধিক কাছের সমতুল্য রয়েছে, বা একই পদ্ধতির ব্যবহার করতে কোডটি পুনর্নির্মাণ এবং পুনর্লিখনের কাছাকাছি যান। 'একবার এটি করুন এবং ভালভাবে করুন' ম্যাক্সিমামটি খারাপভাবে ব্যর্থ হয়।

তদুপরি, পুনরুক্তিকারীর নিজেই কোনও ব্যতিক্রম বাড়াতে হবে কিনা তা চালানোর জন্য চালানোর জন্য একটি অভ্যন্তরীণ 'হেসেক্সট' চেক করা দরকার। এরপরে এই অভ্যন্তরীণ চেকটি গোপন করা হয়েছে যাতে এটি কোনও আইটেম পাওয়ার চেষ্টা করে, ব্যতিক্রমটি ধরতে এবং নিক্ষেপ করা হলে হ্যান্ডলারটি চালিয়ে পরীক্ষা করার প্রয়োজন হয়। এটি অপ্রয়োজনীয় লুকানো আইএমও।


1
এই ব্যবহারের ক্ষেত্রে, আপনি itertools. سائیکل
agগলব্রেইন

0

প্রস্তাবিত উপায় হ'ল স্টপআইটিরেশনটিউটোরিয়ালপয়েন্ট থেকে ফিবোনাকির উদাহরণ দেখুন

#!usr/bin/python3

import sys
def fibonacci(n): #generator function
   a, b, counter = 0, 1, 0
   while True:
      if (counter > n): 
         return
      yield a
      a, b = b, a + b
      counter += 1
f = fibonacci(5) #f is iterator object

while True:
   try:
      print (next(f), end=" ")
   except StopIteration:
      sys.exit()

-2

আমি যেভাবে আমার সমস্যার সমাধান করেছি তা হ'ল এতক্ষণ অবজেক্টের সংখ্যার গণনা রাখা। আমি একটি উদাহরণ পদ্ধতিতে কল ব্যবহার করে একটি সেট পুনরাবৃত্তি করতে চেয়েছিলাম। যেহেতু আমি সেটটির দৈর্ঘ্য এবং এখন পর্যন্ত গণনা করা আইটেমগুলির সংখ্যা জানতাম, তাই কার্যকরভাবে আমার একটি hasNextপদ্ধতি ছিল ।

আমার কোডের একটি সাধারণ সংস্করণ:

class Iterator:
    # s is a string, say
    def __init__(self, s):
        self.s = set(list(s))
        self.done = False
        self.iter = iter(s)
        self.charCount = 0

    def next(self):
        if self.done:
            return None
        self.char = next(self.iter)
        self.charCount += 1
        self.done = (self.charCount < len(self.s))
        return self.char

    def hasMore(self):
        return not self.done

অবশ্যই, উদাহরণটি একটি খেলনা, তবে আপনি ধারণাটি পান। জেনারেটর ইত্যাদির মতো পুনরাবৃত্তের দৈর্ঘ্য পাওয়ার কোনও উপায় না থাকলে এটি কাজ করবে না This

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.