Gibt es einen einfachen Generatorausdruck, der unendliche Elemente ergeben kann?
Dies ist eine rein theoretische Frage. Hier ist keine "praktische" Antwort erforderlich :)
Zum Beispiel ist es einfach, einen endlichen Generator herzustellen:
my_gen = (0 for i in xrange(42))
Um jedoch eine unendliche zu erstellen, muss ich meinen Namespace mit einer Scheinfunktion "verschmutzen":
def _my_gen():
while True:
yield 0
my_gen = _my_gen()
Dinge in einer separaten Datei zu tun und import
später zu tun, zählt nicht.
Ich weiß auch, dass itertools.repeat
das genau das tut. Ich bin gespannt, ob es eine Einzeilerlösung ohne diese gibt.
python
iterator
generator
infinite-loop
Hugomg
quelle
quelle
my_gen
und tun Sie es dannmy_gen = my_gen()
.del _my_gen
wenn Sie die beiden nicht verwechseln möchtenAntworten:
iter
= null Argumente aufrufbar + Sentinel-Wertint()
kehrt immer zurück0
Daher
iter(int, 1)
ist ein unendlicher Iterator. Es gibt offensichtlich eine große Anzahl von Variationen dieses speziellen Themas (besonders wenn Sie eslambda
in die Mischung aufnehmen). Eine Variante von besonderer Bedeutung istiter(f, object())
, dass die Verwendung eines frisch erstellten Objekts als Sentinel-Wert fast einen unendlichen Iterator garantiert, unabhängig davon, welcher Aufruf als erstes Argument verwendet wird.quelle
iter
mit Eigentum zu verwenden,int
das wir oft vergessen.itertools.count
:count = lambda start=0, step=1: (start + i*step for i, _ in enumerate(iter(int, 1)))
iter
-Funktion mit zwei Argumenten aufgerufen wird, verhält sie sich etwas anders als normalerweise :iter(callable, sentinel) -> iterator
. Argument 1callable
wird für jede Iteration des Iterators aufgerufen, bis der Wert von zurückgegeben wirdsentinel
. Da wir jedochint()
immer zurückkehren werden0
, können wir für immer anrufenint()
und niemals 1 erreichen. Dies wird0
itertools
bietet drei unendliche Generatoren:count(start=0, step=1)
: 0, 1, 2, 3, 4, ...cycle(p)
: p [0], p [1], ..., p [-1], p [0], ...repeat(x, times=∞)
: x, x, x, x, ...Ich kenne keine anderen in der Standardbibliothek.
Da Sie nach einem Einzeiler gefragt haben:
quelle
∞
Symbol für jeden, der sich gefragt hat - das Weglassen des Arguments führt zu einer wiederholten Wiederholungiter(int, 1)
Beschwörung. Schade, dassitertools
es keineendlessly()
Methode gibt, deren einziger Zweck dies ist.itertools.count()
ist auch nicht so lesbar.Sie können über eine aufrufbare Datei iterieren und eine Konstante zurückgeben, die sich immer vom Sentinel von iter () unterscheidet
quelle
iter
(hier mit zusätzlichem Sentinel) und die Syntax vonlambda
(hier nur ohne übergebene Parameterreturn 0
) kennt , ist der einzige Ort, an dem man hassen kann, dieser rätselhafteg1
.Ihr Betriebssystem bietet möglicherweise etwas, das als unendlicher Generator verwendet werden kann. ZB unter Linux
offensichtlich ist dies nicht so effizient wie
quelle
\n
ob sie von Zeit zu Zeit erscheint ... Devious! :)Keiner, der intern keinen anderen unendlichen Iterator verwendet, der als Klasse / Funktion / Generator definiert ist (kein Ausdruck, eine Funktion mit
yield
). Ein Generatorausdruck bezieht sich immer auf einen iterierbaren Anoter und filtert und ordnet seine Elemente nur zu. Sie können nicht mit nurmap
und von endlichen zu unendlichen Elementenfilter
wechselnwhile
(oder einemfor
, der nicht endet, was genau das ist, was wir nicht nur mitfor
und mit endlichen Iteratoren haben können).Wissenswertes: PEP 3142 ist oberflächlich ähnlich, aber bei näherer Betrachtung scheint es, dass es immer noch die
for
Klausel erfordert (also nein(0 while True)
für Sie), dh nur eine Abkürzung füritertools.takewhile
.quelle
from itertools import repeat, count, cycle
zählt für die meisten Leute wahrscheinlich als "leicht verfügbar".iter
. Unendliche Iteratoren sind tatsächlich als eingebaute verfügbar - siehe meine Antwort :)Ziemlich hässlich und verrückt (allerdings sehr lustig), aber Sie können Ihren eigenen Iterator aus einem Ausdruck erstellen, indem Sie einige Tricks anwenden (ohne Ihren Namespace nach Bedarf zu "verschmutzen"):
quelle
Vielleicht könnten Sie Dekorateure wie diesen verwenden, zum Beispiel:
Verwendungszweck 1):
Verwendung (2)
Ich denke, es könnte weiter verbessert werden, diese Hässlichen loszuwerden
()
. Dies hängt jedoch von der Komplexität der Sequenz ab, die Sie erstellen möchten. Wenn Ihre Sequenz mithilfe von Funktionen ausgedrückt werden kann, kann im Allgemeinen die gesamte Komplexität und der syntaktische Zucker von Generatoren in einem Dekorator oder einer dekoratorähnlichen Funktion verborgen sein.quelle
def
und Verschluss? ;)(2^x)
, Sie können haben(x)
. Wenn Sie es ein wenig verbessern, möglicherweise auch Fibonacci usw.seq
den Code loswerden und direktwrap