Неужели Итераторы Python получили метод hasNext
?hasNext в итераторах Python?
ответ
Нет, нет такого метода. Исключение составляет конец итерации. См. documentation.
«Легче попросить прощения, чем разрешения». –
«Легче попросить прощения, чем разрешение».: Проверка того, имеет ли итератор следующий элемент, не запрашивает разрешения. Есть ситуации, когда вы хотите проверить существование следующего элемента, не потребляя его. Я бы принял решение catch catch, если был метод 'unnext()', чтобы вернуть первый элемент после проверки того, что он существует, вызывая 'next()'. – Giorgio
@Giorgio, нет способа узнать, существует ли другой элемент без выполнения кода, который его генерирует (вы не знаете, будет ли генератор выполнять 'yield' или нет). Конечно, нетрудно написать адаптер, который хранит результат 'next()' и предоставляет 'has_next()' и 'move_next()'. – avakar
No. Наиболее близкое понятие, скорее всего, StopIteration exception.
Что Python использует исключения для потока управления? Звучит довольно нафтодно. –
Вправо: исключения должны использоваться для обработки ошибок, а не для определения нормального потока управления. – Giorgio
Я считаю, что питон просто имеет следующий() и в соответствии с доком, он бросает исключение нет больше элементов.
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
Если вы действительно необходимо 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 особенности, таким образом, я пытаюсь предупредить подобные комментарии на этот раз ;-)]]
«Верно переписывая алгоритм из эталонной реализации в Java» является худшей причиной для использования метода 'has_next'. Дизайн Python делает невозможным, скажем, использовать 'filter', чтобы проверить, содержит ли массив элемент, соответствующий данному предикату. Высокомерие и близорукость сообщества Python ошеломляют. –
хороший ответ, я копирую это для иллюстрации какого-то шаблона проектирования, взятого из кода Java – madtyn
Я с Python3, и этот код дает мне 'TypeError: iter() возвращен не-итератор' – madtyn
в дополнение ко всем упоминает о StopIteration, Питон «для» петли просто делает то, что вы хотите:
>>> it = iter("hello")
>>> for i in it:
... print i
...
h
e
l
l
o
Вы можете tee
итератор, используя, itertools.tee
и проверьте StopIteration
на первый удар итератора.
Попробуйте метод __length_hint __() из любого объекта итератора:
iter(...).__length_hint__() > 0
Я всегда задавался вопросом, почему на земле у python есть все эти методы __ xxx __? Они кажутся такими уродливыми. –
Законный вопрос! Обычно это синтаксис для методов, которые выставляются встроенной функцией (например, len, на самом деле вызывает __len__). Такая встроенная функция не существует для length_hint, но это фактически ожидающее предложение (PEP424). – fulmicoton
@ mP. эти функции существуют, потому что они иногда необходимы. Они преднамеренно уродливы, потому что они считаются последним средством: если вы их используете, вы знаете, что делаете что-то непитоновое и потенциально опасное (что также может перестать работать в любой момент). –
Там альтернатива к 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
или другого заранее указанного значения для конца итератора, если вы не хотите, как исключение.
, если вы используете None в качестве «дозорного», вы должны быть уверены, что ваш итератор не имеет никаких Nones. вы также можете сделать 'sentinel = object()' и 'next (iterator, sentinel)' и test with 'is'. –
Прецедент, которые приводят меня искать это следующий
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», чтобы проверить, нужно ли ему создавать исключение. Эта внутренняя проверка затем скрыта, чтобы ее нужно было протестировать, пытаясь получить элемент, поймав исключение и запустив обработчик, если он был брошен. Это не нужно скрывать ИМО.
хороший подход для такого вопроса/проблемы, это проверить, что мы имеем в директории (объект/метод/итератора/тип/класс/...)
вы увидите, что dir(iterator)
возвращение __length_hint__
iterator.__length_hint__()
и является положительным до конца итерации.
все.
'__length_hint__' не гарантируется точность: https://www.python.org/dev/peps/pep-0424/. –
Мне это нравится:
While(True):
try:
# Do something with the next value
iterator.next()
except StopIteration:
break
Почему бы просто не использовать 'for ... in'? – bfontaine
Так я решил свою проблему, чтобы сохранить счетчик количества объектов итерации, до сих пор. Я хотел выполнить итерацию по набору, используя вызовы метода экземпляра. Поскольку я знал длину набора и количество элементов, подсчитанных до сих пор, у меня фактически был метод 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
Конечно, пример игрушка один, но вы получите идею. Это не будет работать в случаях, когда нет возможности получить длину итерации, например, генератора и т. Д.
- 1. шаблоны, используемые в итераторах
- 2. Путаница об итераторах и итерациях в Python
- 3. islice на вложенных итераторах
- 4. Оберточные связанные списки в итераторах
- 5. «И окончательно» Блок в итераторах
- 6. Вопросы о итераторах C++
- 7. hasNext() в массиве итераторе
- 8. Ищет строку в двух итераторах в C++
- 9. Реализовать quicksort на двунаправленных итераторах
- 10. Ошибка в итераторах с кодовыми контрактами?
- 11. Scanner & .hasNext() issue
- 12. .hasNext() не работает правильно
- 13. hasNext() method confusion
- 14. Java - ListIterator и hasNext
- 15. Пока hasNext() не закончится
- 16. hasNext() для генератора ES6
- 17. hasNext() сканер продолжает цикл
- 18. java.util.Scanner зависает hasnext()
- 19. Использование «hasNext()» Заявление
- 20. Как правильно использовать hasNext?
- 21. Пояснения к операторам постфикса/префикса на итераторах
- 22. Стоп на итераторах последних элементов C++
- 23. как hasnext() работает в коллекции в Java
- 24. Вопрос о векторах, указателях и итераторах
- 25. Переместить Далее на Итераторах с несколькими именами
- 26. Почему не hasNext() становится ложным?
- 27. Protege: как выразить 'not hasNext'?
- 28. Сканер hasNext() и escape-символы
- 29. Java-сканер с 2 hasNext()
- 30. PHP-эквиваленты .hasNext() и .hasNextLine()?
Связанный: [Как узнать, сгенерирован ли генератор с самого начала?] (Http: // stackoverflow.com/questions/661603/how-do-i-know-if-a-generator-is-empty-from-the-start) – user2314737