Zahlenreihe finden

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
der kleine Fritz
User
Beiträge: 25
Registriert: Montag 18. Dezember 2023, 11:33

Hallo, ich bin noch ein ziemlicher Python-Anfänger und möchte an dieser Stelle fragen ob es über eine for-Schleife oder sonstige Methode möglich ist in einer Liste oder Array von Zahlen (egal ob integer oder float Zahlen)
aus einer Menge von Zahlen eine aufsteigenden Zahlensequenz zu finden. Der Code sollte nur diese Zahlensequenz zurückgeben bis in der Reihe eine niedrigere Zahl auftaucht. ...ich hoffe ich hab mich verständlich ausgedrückt :P

Danke schon mal!
__deets__
User
Beiträge: 14544
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja, das ist moeglich. Und mit dieser Zuversicht versehen kannst du dich jetzt ja an die Umsetzung deiner Hausaufgabe machen, oder? Denn Programmieren auf Zuruf fuer sowas passiert hier eher selten.

Noch ein paar Implementationshinweise: du musst dir merken, was die Zahl davor war, um entscheiden zu koennen, ob du aufsteigend unterwegs bist. Solange das der Fall ist, kann die Zahl davor in die Ergebnisliste gesteckt werden. Am Anfang gibt's da den Randfall, dass man ja keine Zahl davor hat, das muss man durch die Sonderbehandlung zB von dem Wert None abfangen.

Es gibt noch ein paar weiter Fragen, die man klaeren muss. Selbst fuer eine global absteigende Sequenz der Laenge N hat man dann auch N Sequenzen mit aufsteigenden Zahlen. Halt nur ein Element/Sequenz. Ob das auch zaehlt, oder ob die ausgefiltert werden sollen, steht in deiner Aufgabe nicht. Und was passiert, wenn mehrere Sequenzen vorkommen, auch nicht.
der kleine Fritz
User
Beiträge: 25
Registriert: Montag 18. Dezember 2023, 11:33

Danke für den Hinweis und dein Input! Und nein ich bin kein Schüler oder Student, sonder eher älteren Jahrgangs ;-)
Ich arbeite eher als Hobby mit Python und die Aufgabe kam aus dem Buch Python-Challanges.

In der Aufgabenstellung sollen alle aufsteigenden Zahlensequenzen gefunden und ausgegeben werden. Ich habe das im Rahmen einer for - Schleife versucht, aber da finde ich keine Möglichkeit wie man quasi die Elemente in der Liste miteinander vergleicht. Ich habe das schon mit for i in "Liste" und dann if i (n < n+1) ..... Aber da versteht mich leider Python nicht. Ich bräuchte quasi nur ein Befehl und brauche keinen fertigen Code. Das wäre ja langweilig.
__deets__
User
Beiträge: 14544
Registriert: Mittwoch 14. Oktober 2015, 14:29

Man kann das mit pairwise machen. Aber man kann eben auch einfach eine Variable mit dem Wert aus der letzten Iteration belegen.

Code: Alles auswählen

previous = None
for number in sequence: 
    if previous is not None and previous < number: 
        …
    previous = number
der kleine Fritz
User
Beiträge: 25
Registriert: Montag 18. Dezember 2023, 11:33

Super! Ganz lieben Dank für die sehr wertvollen Tipps! Ich versuche es erst mal mit deets Vorschlag, da das schön einfach aussieht ;-) Falls das nicht klappt nehme ich mir pairwise zur Brust.
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mit `pairwise()` und `groupby()` (für streng steigend):

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import groupby, pairwise


def main():
    numbers = [3, 2, 1, 0, 1, 2, 3, 4, 2, 3, 4, 5, 4, 3, 2, 0, 1, 2, 2]

    for is_ascending, group in groupby(
        pairwise(numbers), lambda pair: pair[0] < pair[1]
    ):
        if is_ascending:
            print([*next(group), *(second for _, second in group)])


if __name__ == "__main__":
    main()
Ausgabe:

Code: Alles auswählen

[0, 1, 2, 3, 4]
[2, 3, 4, 5]
[0, 1, 2]
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
der kleine Fritz
User
Beiträge: 25
Registriert: Montag 18. Dezember 2023, 11:33

... was soll ich sagen es hat geklappt!!! Danke!
ziffern = input("geben Sie eine Ziffernfolge ein, die nach einer aufsteigenden Reihe durchsucht werden soll!")
zwichlist = [ ]
lstzif = list(map(int, ziffern))
previous = None
for number in lstzif:
if previous is not None and previous < number:
zwichlist.append(number)
previous = number
print (zwichlist)
Zuletzt geändert von der kleine Fritz am Montag 18. Dezember 2023, 15:35, insgesamt 2-mal geändert.
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@der kleine Fritz: Naja dann war die Frage aber nicht so richtig präzise gestellt, denn die Liste `numbers` in meinem Beispiel enthält ja *drei* aufsteigende Zahlenfolgen. Die Ausgangsfrage hatte zwar nichts zu Ziffern, aber selbst unter der Einschränkung funktioniert die `numbers`-Folge als Beispiel.

Anmerkungen zum Quelltext: Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. `lstzif` oder `zwichlist` sind keine guten Namen. Namen sollen dem Leser verraten was der Wert in dem Programm bedeutet, und nicht zum rätseln zwingen. Grunddatentypen wie `list` oder als Abkürzung `lst` haben in Namen nichts zu suchen.

Man sollte keine Sprachen bei der Namensgebung mischen. Entweder Englisch oder Deutsch, aber nicht mal `ziffern` und an anderer Stelle `number`.

Man muss auch nicht jedes Zwischenergebnis an einen Namen binden. `lstzif` ist beispielsweise unnötig. Überhaupt eine Liste daraus zu machen ist unnötig.

Zwischenstand:

Code: Alles auswählen

#!/usr/bin/env python3


def main():
    digits = input(
        "Geben Sie eine Ziffernfolge ein, die nach einer aufsteigenden Reihe"
        " durchsucht werden soll: "
    )
    result = []
    previous = None
    for number in map(int, digits):
        if previous is not None and previous < number:
            result.append(number)
        previous = number
    print(result)


if __name__ == "__main__":
    main()
Aber funktioniert das wirklich? Einfachstes Beispiel:

Code: Alles auswählen

Geben Sie eine Ziffernfolge ein, die nach einer aufsteigenden Reihe durchsucht werden soll: 12345
[2, 3, 4, 5]
Müsste die 1 da nicht enthalten sein in der Ausgabe?

Edit: Ebenfalls interessanter Randfall wäre die Eingabe von *einer* Ziffer. Zählt das als aufsteigende Zahlenfolge oder nicht?

Edit 2:

Code: Alles auswählen

#!/usr/bin/env python3
from itertools import accumulate

from more_itertools import unique_justseen


def main():
    digits = input(
        "Geben Sie eine Ziffernfolge ein, die nach einer aufsteigenden Reihe"
        " durchsucht werden soll: "
    )
    result = list(unique_justseen(accumulate(map(int, digits), max)))
    print(result)


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
der kleine Fritz
User
Beiträge: 25
Registriert: Montag 18. Dezember 2023, 11:33

ja das stimmt. Hängt wahrscheinlich mit "previous = None" zusammen. Da wird dann die erste Ziffer eventuell nicht berücksichtigt.
der kleine Fritz
User
Beiträge: 25
Registriert: Montag 18. Dezember 2023, 11:33

@blackjack: Danke für die Tipps bezüglich Namengebung von Listen etc. Ich code hier nur ein wenig für mich selber rum als Hobby um meine grauen Zellen fitt zu halten. Die codes liest sonst keiner, aber ich werde mehr Disziplin bei der Namengebung walten lassen.

Ich habe nun meinen code angepasst:

lstzif = [0]
lstzif1 = lstzif + list(map(int, ziffern))

Dadurch wird nun auch die erste Zifferneingabe berücksichtigt.
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@der kleine Fritz: Man programmiert immer auch für Fremde, denn erfahrungsgemäss ist man das nach einer gewissen Zeit selbst, der Fremde der sich anhand der Namen und des Codes wieder in den Code einarbeiten muss und dann von sinnvollen Namen profitiert. Weil man eben nicht rätseln muss, was man da mal mit gemeint haben könnte. Eine gute, sinnvolle, konsistente Namensgebung ist grundlegender Bestandteil vom programmieren. Das ist nicht einfach nur Kosmetik oder etwas das man nachträglich mal machen kann. Wenn man keinen guten Namen für Werte oder Strukturen findet , deutet das oft darauf hin, dass man das Problem oder die Lösung noch nicht wirklich verstanden hat, oder das man unpassendes in einer Struktur zusammenfasst, oder das Funktionen oder Methoden zu viel machen und/oder Dinge die nicht zusammengehören. Schlechte oder gar falsche Namen können einen irreführen und damit Programmierfehler zur Folge haben.

Und im letzten Beitrag kommt ein weiteres No-Go dazu: Namen nummerieren. Entweder ist das dann ein nichtssagender Name der einfach nur eine Nummer angehängt bekommen hat um ihn rein formal von anderen Namen zu unterscheiden, oder man will dafür eigentlich keine Einzelnamen und Werte, sondern eine Datenstruktur.

In diesem Fall will man aber eher gar keinen neuen Namen, sondern die ursprüngliche Liste mit der 0 um weitere Elemente erweitern. Entweder mit der `extend()`-Methode, oder mit Syntax für Listen:

Code: Alles auswählen

    numbers = [0]
    numbers.extend(map(int, digits))

    # oder

    numbers = [0, *map(int, digits)]
Wenn man die Liste nicht tatsächlich erstellen möchte, könnte man das auch mit `chain.from_iterables()` aus dem `itertools`-Modul lösen, oder mit `more_itertools.prepend()`.

Eine andere Lösung käme aber ganz ohne Veränderung/Erweiterung der Eingabedaten aus und würde den Code in der Schleife sogar noch vereinfachen. Überleg mal was das für eine Folge hat, wenn man die Eingabe durch einen Startwert erweitert. Statt diesem Umweg zu nehmen, könnte man das auch direkter machen.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
der kleine Fritz
User
Beiträge: 25
Registriert: Montag 18. Dezember 2023, 11:33

Ich habe nun abschließend das Problem so gelöst und dabei sogar eine Liste eingespart.

Code: Alles auswählen

ziffern = input("geben Sie eine Ziffernfolge ein, die nach einer aufsteigenden Reihe durchsucht werden soll!")
zwichlist = []
lstzif = list(map(int, ziffern))
previous = None
if lstzif [0] < lstzif [1]:
    zwichlist.append (lstzif [0])
for number in lstzif:
    if previous is not None and previous < number:
        zwichlist.append(number)
    previous = number
print (zwichlist)
Beim nächsten Code werde ich auf die Namensgebung von Listen, Variablen oder Arrays mehr Sorgfalt walten lassen. :)
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum achtest Du nicht gleich auf die Namensgebung????

Bist Du Dir sicher, dass das das gewünschte Ergebnis ist?

Code: Alles auswählen

ziffern = "1234512345"
-> [1, 2, 3, 4, 5, 2, 3, 4, 5]
Statt des Sonderfalls vor der Schleife abzuarbeiten, wäre es besser, direkt in der Schleife die "richtige" Bedingung zu nutzen:

Code: Alles auswählen

digits = input("geben Sie eine Ziffernfolge ein, die nach einer aufsteigenden Reihe durchsucht werden soll!")
numbers = list(map(int, digits))
previous = None
result = []
for number in numbers:
    if previous is None or previous < number:
        result.append(number)
    previous = number
print(result)
Antworten