hasnext() für Python-Iteratoren?

Lesezeit: 5 Minuten

Juanjo Contis Benutzeravatar
Juanjo Conti

Haben Python-Iteratoren eine hasnext Methode?

  • Verwandt: Woher weiß ich, ob ein Generator von Anfang an leer ist?

    – Benutzer2314737

    5. Mai 2017 um 10:58

  • So etwas gibt es derzeit nicht. Und ich denke, der richtige Weg, dies zu tun, besteht darin, etwas hinzuzufügen next Und has_next Methode in Iteratoren selbst, da diese Methoden nicht unabhängig definiert werden sollten.

    – Shiv Krishna Jaiswal

    19. Februar um 15:47 Uhr

Derrick Zhangs Benutzeravatar
Derrick Zhang

Die Alternative zum Fangen StopIteration ist zu verwenden next(iterator, default_value).

Zum Beispiel:

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

Auf diese Weise können Sie nachsehen None um zu sehen, ob Sie das Ende des Iterators erreicht haben, wenn Sie es nicht auf die Ausnahmeart machen möchten.

Wenn Ihr Iterable enthalten kann None Werte müssen Sie stattdessen einen Sentinel-Wert definieren und prüfen:

>>> sentinel = object()
>>> a = iter([None, 1, 2])
>>> elem = next(a, sentinel)
>>> if elem is sentinel:
...     print('end')
... 
>>>

  • Wenn Sie None als „Sentinel“ verwenden, stellen Sie am besten sicher, dass Ihr Iterator keine Nones hat. könntest du auch machen sentinel = object() Und next(iterator, sentinel) und testen mit is.

    – Sam Boosalis

    3. Okt. 2013 um 18:00 Uhr


  • Wenn ich @samboosalis folge, würde ich lieber die integrierte Version verwenden unittest.mock.sentinel Objekt, mit dem Sie ein explizites schreiben können next(a, sentinel.END_OF_ITERATION) und dann if next(...) == sentinel.END_OF_ITERATION

    – ClementWalter

    1. Dezember 2018 um 19:40 Uhr

  • Das Problem besteht darin, dass Sie auf diese Weise auch den nächsten Wert aus dem Iterator VERBRAUCHEN. hasNext in Java verbraucht nicht den nächsten Wert.

    – Alan Franzoni

    17. Juli 2020 um 12:18 Uhr

Nein, eine solche Methode gibt es nicht. Das Ende der Iteration wird durch eine Ausnahme angezeigt. Siehe die Dokumentation.

  • „Es ist einfacher, um Vergebung zu bitten als um Erlaubnis.“

    Roger Pate

    27. Dezember 2009 um 18:57 Uhr

  • „Es ist einfacher, um Vergebung zu bitten als um Erlaubnis.“: Die Überprüfung, ob ein Iterator ein nächstes Element hat, bedeutet nicht, um Erlaubnis zu bitten. Es gibt Situationen, in denen Sie die Existenz eines nächsten Elements testen möchten, ohne es zu verbrauchen. Ich würde die Try-Catch-Lösung akzeptieren, wenn es eine gäbe unnext() Methode, um das erste Element zurückzusetzen, nachdem ich durch Aufruf überprüft habe, ob es existiert next().

    – Giorgio

    24. Dezember 2012 um 20:26

  • @Giorgio, es gibt keine Möglichkeit herauszufinden, ob ein anderes Element existiert, ohne den Code auszuführen, der es generiert (Sie wissen nicht, ob der Generator ausgeführt wird). yield oder nicht). Es ist natürlich nicht schwierig, einen Adapter zu schreiben, der das Ergebnis speichert next() und sorgt has_next() Und move_next().

    – Avakar

    24. Dezember 2012 um 21:10 Uhr

  • Die gleiche Idee könnte zur Umsetzung verwendet werden hasNext() Methode (zum Erzeugen, Zwischenspeichern und Zurückgeben von „true“ bei Erfolg oder von „false“ bei Fehler). Dann beides hasNext() Und next() würde von einem gemeinsamen Basiswert abhängen getNext() Methode und zwischengespeichertes Element. Ich verstehe wirklich nicht, warum next() sollte nicht in der Standardbibliothek enthalten sein, wenn es so einfach ist, einen Adapter zu implementieren, der dies bereitstellt.

    – Giorgio

    24. Dezember 2012 um 21:21


  • @LarsH: Du meinst zB einen Iterator, der aus einer Datei liest, die beim Lesen geändert werden kann? Ich stimme zu, dass dies ein Problem sein kann (das sich auf alle Bibliotheksanbieter auswirkt). next() Und hasNext() Methode, nicht nur eine hypothetische Python-Bibliothek). Also ja, next() Und hasNext() wird schwierig, wenn der Inhalt des gescannten Streams davon abhängt Wenn Elemente werden gelesen.

    – Giorgio

    25. Januar 2013 um 6:42


Benutzeravatar von Alex Martelli
Alex Martelli

Nein, aber Sie können Ihre eigene iterierbare Wrapper-Klasse implementieren, die Folgendes tut:

from collections.abc import Iterator

class hn_wrapper(Iterator):
    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

Dann können Sie es so verwenden:

x = hn_wrapper('ciao')
while x.hasnext():
    print(next(x))

und es wird emittieren

c
i
a
o

  • Die Implementierung wäre etwas pythonischer hasnext() wie next()also Umbenennen der Methode in hn_wrapper.__hasnext__() und dann eine Funktion der obersten Ebene definieren, die diese Methode aufruft def hasnext(iterable): return iterable.__hasnext__().

    – Boris Werchowski

    30. April um 23:20 Uhr


Benutzeravatar von Brian Clapper
Brian Clapper

Zusätzlich zu allen Erwähnungen von StopIterationder Python for Schleife macht, was Sie wollen:

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

jujs Benutzeravatar
juj

Probieren Sie die Methode __length_hint__() von einem beliebigen Iteratorobjekt aus aus:

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

Sykoras Benutzeravatar
Sykora

Du kannst tee der Iterator verwendet, itertools.teeund prüfen Sie, ob StopIteration auf dem Tee-Iterator.

hasNext übersetzt in gewisser Weise die StopIteration Ausnahme, z.B.:

>>> 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

1450200cookie-checkhasnext() für Python-Iteratoren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy