Python – Die Collatz-Sequenz
Beachten Sie zunächst, wie Sie Berechnungen duplizieren:
print(num//2)num = num //2
Dies verursacht möglicherweise keine Probleme mit diesem speziellen Code, ist jedoch keine gute Vorgehensweise. Sie machen doppelt so viel Arbeit wie nötig, was zu Leistungsproblemen führen kann, wenn Sie anfangen, komplizierteren Code zu schreiben. Führen Sie die Berechnung einmal durch und speichern Sie das Ergebnis. In diesem Fall müssen Sie jedoch nur diese Zeilen umkehren und num
:
num = num // 2print(num)
Stellen Sie außerdem sicher, dass Sie einen angemessenen Abstand um Operatoren haben und konsistent sind.
Ihre if
und elif
Fälle schließen sich gegenseitig aus, und Ihr else
sollte niemals vorkommen. Wenn die erste Bedingung wahr ist, muss die andere falsch sein und umgekehrt. Es gibt keine Notwendigkeit für die zweite Prüfung. Nach dem Umschreiben werden Sie feststellen, dass das Drucken in jedem Fall nicht erforderlich ist. Sie können einfach danach drucken:
while num > 1: if num % 2 == 0: num = num // 2 else: num = 3 * num + 1 print(num)
Da Sie num
nur eine von zwei Optionen basierend auf einer Bedingung neu anfügen, kann auch hier ein bedingter Ausdruck sauber verwendet werden:
while num > 1: num = (num // 2) if num % 2 == 0 else (3 * num + 1) print(num)
Die geschweiften Klammern sind nicht notwendig, aber ich denke, sie sind hier aufgrund der Anzahl der beteiligten Operatoren nützlich.
Das Drucken der Zahlen ist hier nicht ideal. In den meisten Codes müssen Sie in der Lage sein, die von Ihnen erstellten Daten zu verwenden. Wenn Sie die erzeugte Sequenz analysieren wollten, müssten Sie etwas tun, um das stdout abzufangen, was teuer und übermäßig kompliziert ist. Machen Sie es zu einer Funktion, die eine Liste ansammelt und zurückgibt. In den folgenden Beispielen habe ich auch einige Typhinweise hinzugefügt, um den Datentyp klarer zu machen:
from typing import Listdef collatz(starting_num: int) -> List: nums = num = starting_num while num > 1: num = (num // 2) if num % 2 == 0 else (3 * num + 1) nums.append(num) return nums
Oder ein viel sauberer Ansatz besteht darin, ihn zu einem Generator zu machen, der die Zahlen liefert:
# Calling this function returns a generator that produces ints# Ignore the two Nones, as they aren't needed for this kind of generatordef collatz_gen(starting_num: int) -> Generator: yield starting_num num = starting_num while num > 1: num = (num // 2) if num % 2 == 0 else (3 * num + 1) yield num>>> list(collatz_gen(5))
Es gibt ein paar bemerkenswerte Dinge über getNum
:
Python verwendet “snake_case”, nicht “camelCase”.
Ihre Verwendung von global num
hier ist unnötig und verwirrend. Wie zuvor explizit return
alle Daten, die die Funktion erzeugt:
def get_num() -> int: raw_num = input("> ") try: return int(raw_num) except ValueError: print('Please enter a number') return get_num()
Beachten Sie, dass wir anstelle einer globalen num
nur die Nummer zurückgeben. Ich habe die Dinge auch ein wenig auseinandergehalten und einige passendere Namen verwendet. Konzeptionell würde ich sagen, dass num = input("> ")
falsch ist. Zum Zeitpunkt der Ausführung enthält num
keine Zahl (es enthält eine Zeichenfolge).
Dies ist keine gute Verwendung der Rekursion. Es wird Ihnen wahrscheinlich keine Probleme bereiten, aber wenn Ihr Benutzer wirklich dumm ist und ~ 1000 Mal falsche Daten eingibt, stürzt Ihr Programm ab. Verwenden Sie einfach eine Schleife:
def get_num() -> int: while True: raw_num = input("> ") try: return int(raw_num) except ValueError: print('Please enter a number')
Seien Sie in Sprachen wie Python vorsichtig, wenn Sie die Rekursion in Fällen verwenden, in denen Sie keine Garantie dafür haben, wie oft die Funktion erneut ausgeführt wird.
Ich würde dies wahrscheinlich auch etwas näher an ask_for_num
nennen. “get” macht nicht sehr deutlich, woher die Daten kommen.
Insgesamt erhalten Sie am Ende:
from typing import Generatordef collatz_gen(starting_num: int) -> Generator: yield starting_num num = starting_num while num > 1: num = (num // 2) if num % 2 == 0 else (3 * num + 1) yield numdef ask_for_num() -> int: while True: raw_num = input("> ") try: return int(raw_num) except ValueError: print('Please enter a number')
Welches kann verwendet werden wie:
num = ask_for_num()for n in collatz_gen(num): print(n)