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
'programing' 카테고리의 다른 글
Java에서의 ClassCast Exception 설명 (0) | 2022.10.30 |
---|---|
Python에서 클래스 변수를 정의하는 올바른 방법 (0) | 2022.10.30 |
검출되지 않은 오류:불변 위반:요소 유형이 잘못되었습니다. 문자열(내장 구성 요소에 대한) 또는 클래스/함수가 필요하지만: 개체를 받았습니다. (0) | 2022.10.30 |
phpMyAdmin 3.2.4를 사용하여 뷰를 편집하려면 어떻게 해야 합니까? (0) | 2022.10.30 |
디버깅 로그 인쇄 방법 (0) | 2022.10.30 |