programing

python의 반복기에서 has_next가 있습니까?

kingscode 2022. 10. 30. 20:38
반응형

python의 반복기에서 has_next가 있습니까?

Python의 반복자라면has_next방법?

다른 방법이 있습니다.StopIteration을 사용하여next(iterator, default_value).

예:

>>> 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)를 참조해 주세요).[Python 2.6이 1년 이상 사용되었기 때문에 이 노트는 중복되어 있다고 생각하실 수 있습니다.그러나 응답에서 Python 2.6 기능을 사용할 때 어떤 코멘터나 다른 코멘트가 2.6 기능임을 지적할 의무가 있다고 생각되는 경우가 많기 때문에 저는 이러한 코멘트를 회피하려고 합니다.]

===

Python3의 경우 다음과 같이 변경합니다.

from collections.abc import Iterator  # since python 3.3 Iterator is here

class hn_wrapper(Iterator):  # need to subclass Iterator rather than object
  def __init__(self, it):
    self.it = iter(it)
    self._hasnext = None
    
  def __iter__(self): 
    return self
  
  def __next__(self):        # __next__ vs next in python 2
    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

StopIteration에 대한 모든 언급과 더불어 Python의 "for" 루프는 당신이 원하는 것을 할 수 있습니다.

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

임의의 반복 개체에서 __length_hint__() 메서드를 시도합니다.

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

넌 할 수 있다.tee리터레이터를 사용합니다.itertools.tee, 및 을 확인합니다.StopIteration티어 리터레이터에서.

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
  • StopIteration문서: http://docs.python.org/library/exceptions.html#exceptions.StopIteration
  • python의 반복기 및 생성기에 대한 일부 기사: http://www.ibm.com/developerworks/library/l-pycon.html

아니요. 가장 유사한 개념은 StopIteration 예외입니다.

python에는 next()만 있는 것으로 알고 있으며, doc에 따르면 더 이상 요소가 없다는 예외가 발생한다고 합니다.

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

이를 검색하기 위한 사용 사례는 다음과 같습니다.

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 

여기서 hasnext()를 사용할 수 있습니다.

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)

어느 쪽이 더 깨끗한가요?유틸리티 클래스를 정의함으로써 문제를 회피할 수 있는 것은 분명하지만, 그 결과 20여 개의 서로 거의 동등한 회피책이 각각의 기호에 따라 급증하고 있습니다.다른 회피책을 사용하는 코드를 재사용하려면 단일 응용 프로그램에서 거의 동등한 복수의 회피책을 사용하거나 pi를 우회해야 합니다.같은 어프로치를 사용하기 위해 코드를 체크하고 다시 씁니다.'한 번 하면 잘 한다'는 격언은 크게 실패한다.

또한 반복기 자체는 예외를 발생시킬 필요가 있는지 확인하기 위해 내부 'hasnext' 체크를 실행해야 합니다.이 내부 체크는 숨겨져 있기 때문에 아이템을 취득하여 예외를 검출하고 핸들러를 실행하는 것으로 테스트해야 합니다.이것은 IMO를 숨길 필요가 없습니다.

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★는 「」로 됩니다.StopIteration(자세한 것은 이쪽).


이는 python 원칙 EAFP(허가보다 용서를 구하는 것이 더 쉽다)에 따릅니다. a.has_next방법은 LBIL(도약하기 전 살펴보기) 원칙을 따르고 이 핵심 비단뱀 원칙과 모순됩니다.

이 흥미로운 기사는 두 가지 개념을 더 자세히 설명합니다.

권장되는 방법은 StopIteration입니다.튜토리얼 포인트에서 피보나치 예를 참조하십시오.

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

또한 임의의 반복기를 랩하고 다음 값이 있는 경우 질문에 응답하는 도우미 생성기를 구현할 수도 있습니다.

온라인으로 시험해 보세요!

def has_next(it):
    first = True
    for e in it:
        if not first:
            yield True, prev
        else:
            first = False
        prev = e
    if not first:
        yield False, prev

for has_next_, e in has_next(range(4)):
    print(has_next_, e)

출력:

True 0
True 1
True 2
False 3

단점이자 은 한 , 에서는 특히 이을 사용할 수 없는 . 대부분의 작업에서는 완전히 문제가 없지만 일부 작업에서는 특히 사용자가 이 방법을 사용하는 경우 허용되지 않을 수 있습니다.has_next()는 이 사전 읽기 논리를 인식하지 못하기 때문에 잘못 사용할 수 있습니다.

위의 코드는 무한 반복기에도 사용할 수 있습니다.

내가 모든 has_next()전혀 문제가 되지 않았고 오히려 큰 도움이 되었습니다.미리 읽기 논리를 알아두면 됩니다.

저뿐일지도 모르지만, 저는 https://stackoverflow.com/users/95810/alex-martelli의 답변을 좋아하지만, 이것을 읽기가 조금 더 쉽다고 생각합니다.

from collections.abc import Iterator  # since python 3.3 Iterator is here

class MyIterator(Iterator):  # need to subclass Iterator rather than object
  def __init__(self, it):
    self._iter = iter(it)
    self._sentinel = object()
    self._next = next(self._iter, self._sentinel)
    
  def __iter__(self): 
    return self
  
  def __next__(self):        # __next__ vs next in python 2
    if not self.has_next():
      next(self._iter)  # raises StopIteration

    val = self._next
    self._next = next(self._iter, self._sentinel)
    return val
  
  def has_next(self):
    return self._next is not self._sentinel

"StopIteration" 실행을 처리하는 방법은 모든 반복을 읽기 위해 매우 간단합니다.

    end_cursor = False
    while not end_cursor:
        try:
            print(cursor.next())
        except StopIteration:
            print('end loop')
            end_cursor = True
        except:
            print('other exceptions to manage')
            end_cursor = True

때할 수 있는 가 있다고 합니다.has_next 이 , 「」로할 필요가 있습니다. 이 경우 리터레이터를 로 장식해야 합니다.has_next정의되어 있습니다.

이 질문에 대한 답변에서 나온 개념을 조합한 것이, 나에게 있어서 훌륭한 간결한 솔루션(python 3.9)이라고 생각되는 것을 실장하고 있습니다.

_EMPTY_BUF = object()


class BufferedIterator(Iterator[_T]):
    def __init__(self, real_it: Iterator[_T]):
        self._real_it = real_it
        self._buf = next(self._real_it, _EMPTY_BUF)

    def has_next(self):
        return self._buf is not _EMPTY_BUF

    def __next__(self) -> _T_co:
        v = self._buf
        self._buf = next(self._real_it, _EMPTY_BUF)
        if v is _EMPTY_BUF:
            raise StopIteration()
        return v

가장 큰 차이점은 이다.has_next이며, 「」, 「반복자」도 취급합니다.None★★★★★★ 。

테스트 및 사용 예시와 함께 여기에 있는 Gist에 이 내용을 추가했습니다.

매우 흥미로운 질문입니다만, 이 「hasnext」설계는 leetcode에 포함되어 있습니다.https://leetcode.com/problems/iterator-for-combination/

실장은 다음과 같습니다.

class CombinationIterator:

def __init__(self, characters: str, combinationLength: int):
    from itertools import combinations
    from collections import deque
    self.iter = combinations(characters, combinationLength)
    self.res = deque()


def next(self) -> str:
    if len(self.res) == 0:
        return ''.join(next(self.iter))
    else:
        return ''.join(self.res.pop())


def hasNext(self) -> bool:
    try:
        self.res.insert(0, next(self.iter))
        return True
    except:
        return len(self.res) > 0

문제를 해결하는 방법은 지금까지 반복된 개체 수를 유지하는 것입니다.인스턴스 메서드에 대한 호출을 사용하여 세트에 대해 반복하고 싶었습니다. 있었기 세어 본 결과, 세트로 되어 있는 의 수를 알 수 있었습니다.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

물론 그 예는 장난감입니다만, 이해하실 수 있습니다.발전기 등 반복 가능한 길이를 구할 방법이 없는 경우에는 작동하지 않습니다.

언급URL : https://stackoverflow.com/questions/1966591/has-next-in-python-iterators

반응형