IT

파이썬 반복자에서 hasNext?

lottoking 2020. 6. 25. 07:47
반응형

파이썬 반복자에서 hasNext?


파이썬 반복자가 hasNext메소드를 얻지 못했습니까 ?


아니요, 그러한 방법은 없습니다. 반복 종료는 예외로 표시됩니다. 설명서를 참조하십시오 .


StopIteration를 사용 하는 대안이 있습니다 next(iterator, default_value).

exapmle의 경우 :

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

따라서 None예외적 인 방법을 원하지 않으면 반복자 끝의 미리 지정된 값을 감지 하거나 다른 값을 감지 할 수 있습니다 .


당신이 정말로 경우 필요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)내장으로 사용 하려면 Python 2.6 이상이 필요합니다. 이전 버전의 Python을 사용 self.it.next()하는 경우 대신 next(x)사용하십시오 (예제 사용법 과 유사 ). [[파이썬 2.6이 1 년 넘게 사용되어 왔기 때문에이 노트가 중복되었다고 생각할 수도 있습니다. 그러나 응답에 파이썬 2.6 기능을 사용할 때보 다 자주, 일부 주석가 또는 다른 사람들이 지적해야 할 의무가 있다고 생각합니다) 그것들 2.6 가지 기능이므로, 그런 의견을 한 번만 포기하려고합니다 ;-)]]


StopIteration에 대한 언급 외에도 Python "for"루프는 단순히 원하는 것을 수행합니다.

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


반복자 객체에서 __length_hint __ () 메소드를 시도하십시오.

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

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

You can tee the iterator using, itertools.tee, and check for StopIteration on the teed iterator.


No. The most similar concept is most likely a StopIteration exception.


I believe python just has next() and according to the doc, it throws an exception is there are no more elements.

http://docs.python.org/library/stdtypes.html#iterator-types


The use case that lead me to search for this is the following

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 

where hasnext() is available, one could do

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)

which to me is cleaner. Obviously you can work around issues by defining utility classes, but what then happens is you have a proliferation of twenty-odd different almost-equivalent workarounds each with their quirks, and if you wish to reuse code that uses different workarounds, you have to either have multiple near-equivalent in your single application, or go around picking through and rewriting code to use the same approach. The 'do it once and do it well' maxim fails badly.

Furthermore, the iterator itself needs to have an internal 'hasnext' check to run to see if it needs to raise an exception. This internal check is then hidden so that it needs to be tested by trying to get an item, catching the exception and running the handler if thrown. This is unnecessary hiding IMO.


Suggested way is StopIteration. Please see Fibonacci example from tutorialspoint

#!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()

good approach for such question/problems is check what we have in dir(object/method/iterator/type/class/ ...)

you will see that dir(iterator) return __length_hint__

and iterator.__length_hint__() is positive until end of the iteration.

that's it.


The way I solved my problem is to keep the count of the number of objects iterated over, so far. I wanted to iterate over a set using calls to an instance method. Since I knew the length of the set, and the number of items counted so far, I effectively had an hasNext method.

A simple version of my code:

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

Of course, the example is a toy one, but you get the idea. This won't work in cases where there is no way to get the length of the iterable, like a generator etc.

참고URL : https://stackoverflow.com/questions/1966591/hasnext-in-python-iterators

반응형