from itertools import groupby, islice
def morris():
morris = '1'
yield morris
while True:
morris = groupby(morris)
morris = ((len(list(group)), key) for key, group in morris)
morris = ((str(l), k) for l, k in morris)
morris = ''.join(''.join(t) for t in morris)
yield morris
print list(islice(morris(), 10))
Zunächst einmal würde ich das Iterator unendlich machen und lassen die Verbraucher entscheiden, wie viel davon er will. Auf diese Weise könnte er entweder jede Morris-Nummer erhalten, die kürzer als x ist oder die ersten x-Zahlen, etc.
Dann gibt es natürlich keine Notwendigkeit, die ganze Liste der vorherigen Morris-Nummern in einer Liste zu speichern, da die Rekursion nur ist n := f(n-1)
sowieso.
Schließlich ist die Verwendung von itertools, um ihm einen funktionalen Touch zu geben, immer ein oder zwei Punkte wert;) Ich spalte den Generatorausdruck in mehrere Zeilen, um es ein bisschen einfacher für das Auge zu machen.
Die Haupthässlichkeit in dieser Lösung kommt von der Tatsache, dass len()
kann nicht auf einem Iterator aufgerufen werden und gibt uns ein int, wo wir eine str benötigen. Der andere Haken ist die verschachtelte Str. Join), um das Ganze wieder in eine Str zu glätten.
Wenn Sie die Sequenz von beliebigen Zahlen beginnen soll, definieren Sie die Funktion wie folgt aus:
def morris(morris=None):
if morris is None:
morris = '1'
[...]
Wenn Sie um diesen Generator drehen möchten, können Sie es wie folgt schreiben:
def morris():
morris = '1'
yield morris
while True:
print morris
morris = ''.join(''.join(t)
for t in ((str(len(list(group))), key)
for key, group in groupby(morris)))
yield morris
Ich bin mir nicht sicher, ob ich die Aufteilung in zwei Funktionen mag, aber dies scheint die beste Lösung zu sein:
Hoffe es gefällt dir!
Es klingt wie yo Du fragst nach dem Fischschlag-Tanz. Das kombiniert Monty Python und Morris Dancing ... :-) –
Wenn dieses Ding nicht mindestens 10 Zeichen benötigt, hätte ich nur geantwortet mit: D –
Warum gibt ihr beide() ing und speichert Werte auf einem [] ? – Javier