Derzeit mache ich das:
try:
something = iterator.next()
# ...
except StopIteration:
# ...
Aber ich möchte einen Ausdruck, den ich in eine einfache if
Aussage einfügen kann. Ist etwas eingebaut, das diesen Code weniger ungeschickt aussehen lässt?
any()
False
Gibt zurück, wenn eine Iterable leer ist. Wenn dies nicht der Fall ist, werden möglicherweise alle Elemente durchlaufen. Ich brauche es nur, um den ersten Artikel zu überprüfen.
Jemand fragt, was ich versuche zu tun. Ich habe eine Funktion geschrieben, die eine SQL-Abfrage ausführt und deren Ergebnisse liefert. Wenn ich diese Funktion aufrufe, möchte ich manchmal nur wissen, ob die Abfrage etwas zurückgegeben hat, und darauf basierend eine Entscheidung treffen.
Antworten:
any
geht nicht über das erste Element hinaus, wenn es wahr ist. Falls der Iterator etwas Falsches liefert, können Sie schreibenany(True for _ in iterator)
.quelle
any((x > 100 for x in xrange(10000000)))
und dann rennenany((x > 10000000 for x in xrange(100000000)))
- der zweite sollte viel länger dauern.sum(1 for _ in itertools.islice(iterator, max_len)) >= max_len
all(False for _ in iterator)
auch prüfen, ob der Iterator leer ist. (Alle geben True zurück, wenn der Iterator leer ist, andernfalls stoppt er, wenn er das erste False-Element sieht.)Wenn in Python 2.6+ der Name
sentinel
an einen Wert gebunden ist, den der Iterator möglicherweise nicht liefern kann,Wenn Sie keine Ahnung haben, was der Iterator möglicherweise liefern könnte, erstellen Sie Ihren eigenen Sentinel (z. B. oben in Ihrem Modul) mit
Andernfalls könnten Sie in der Sentinel-Rolle jeden Wert verwenden, den Sie "kennen" (basierend auf Anwendungsüberlegungen), den der Iterator möglicherweise nicht liefern kann.
quelle
if not next(iterator, None):
war ausreichend, da ich sicher war, dass keiner nicht Teil der Artikel sein würde. Danke, dass du mich in die richtige Richtung gelenkt hast!not
True für jedes falsche Objekt zurückgegeben wird, z. B. für leere Listen, False und Null.is not None
ist sicherer und meiner Meinung nach klarer.Dies ist nicht wirklich sauberer, aber es zeigt eine Möglichkeit, es verlustfrei in eine Funktion zu packen:
Dies ist nicht wirklich pythonisch, und für bestimmte Fälle gibt es wahrscheinlich bessere (aber weniger allgemeine) Lösungen, wie die nächste Standardeinstellung.
Dies ist nicht allgemein, da None in vielen Iterables ein gültiges Element sein kann.
quelle
next()
.tee
in itertools müssen jedes einzelne Element vom ursprünglichen Iterator fernhalten, falls esany_check
jemals weitergehen muss. Dies ist schlimmer als nur das Konvertieren des ursprünglichen Iterators in eine Liste.Sie können verwenden:
Für den Codeleser ist dies jedoch nicht erklärend
quelle
Der beste Weg, dies zu tun, ist mit einem
peekable
vonmore_itertools
.Passen Sie nur auf, wenn Sie den alten Iterator beibehalten, wird dieser Iterator erweitert. Von da an müssen Sie den neuen Peekable-Iterator verwenden. Wirklich erwartet Peekable jedoch, dass es das einzige Stück Code ist, das diesen alten Iterator modifiziert, so dass Sie die Refs des alten Iterators, der herumliegt, sowieso nicht behalten sollten.
quelle
Wie wäre es mit:
quelle
class NotSet: pass
undif next(i, NotSet) is NotSet: print("Iterator is empty")
__length_hint__
schätzt die Länge vonlist(it)
- es ist jedoch eine private Methode:quelle
Dies ist ein Overkill-Iterator-Wrapper, mit dem im Allgemeinen überprüft werden kann, ob ein nächstes Element vorhanden ist (durch Konvertierung in einen Booleschen Wert). Natürlich ziemlich ineffizient.
Ausgabe:
quelle
Ein bisschen spät, aber ... Sie könnten den Iterator in eine Liste verwandeln und dann mit dieser Liste arbeiten:
quelle