HasNext в итераторах Python?

Неужели итераторы Python получили метод hasNext?

Ответ 1

Нет, такого метода нет. Исключение составляет конец итерации. См. Документацию .

Ответ 2

В качестве альтернативы 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 или другое заданное значение для конца итератора, если вы не хотите, чтобы путь исключения.

Ответ 3

Если вы действительно нуждаетесь a has-next (потому что вы просто верно транскрибируете алгоритм из эталонной реализации в Java, скажем, или потому, что пишете прототип, который понадобится быть легко перенесенным на Java, когда он закончится), легко получить его с небольшим классом-оболочкой. Например:

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 существует уже более года - но чаще всего, когда я использую функции Python 2.6 в ответе, какой-либо комментатор или другой пользователь чувствует обязанность указывать что у них 2,6 функции, поэтому я пытаюсь предотвратить такие комментарии за один раз; -)]]

Ответ 4

Попробуйте метод __length_hint __() из любого объекта итератора:

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

Ответ 5

В дополнение ко всем упоминаниям StopIteration цикл "for" Python просто делает то, что вы хотите:

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

Ответ 6

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

Ответ 8

Вы можете tee использовать итератор, itertools.tee, и проверить на StopIteration на итераторе teed.

Ответ 10

Пример использования, который приведет меня к поиску, следующий:

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)

который мне чище. Очевидно, что вы можете решать проблемы, задавая классы утилиты, но тогда случается, что у вас есть двадцатичетных разных почти эквивалентных обходных пути, каждый из которых связан с их причудами, и если вы хотите повторно использовать код, который использует разные обходные пути, вам нужно либо имеют несколько близких к эквиваленту в одном приложении, или обойти выбор и переписывание кода для использования того же подхода. "Делайте это один раз и делайте это хорошо", максимум терпит неудачу.

Кроме того, сам итератор должен иметь внутреннюю проверку "hasnext", чтобы проверить, нужно ли ей создавать исключение. Эта внутренняя проверка затем скрыта, чтобы ее нужно было протестировать, пытаясь получить элемент, поймав исключение и запустив обработчик, если он был брошен. Это не нужно скрывать ИМО.

Ответ 11

Хороший подход для таких вопросов/проблем - проверка того, что у нас есть в каталоге (object/method/iterator/type/class/...)

вы увидите, что dir(iterator) return __length_hint__

и iterator.__length_hint__() положительны до конца итерации.

что он.

Ответ 12

Мне это нравится:

While(True):
    try:
        # Do something with the next value
        iterator.next()
    except StopIteration:
        break