Dictionary Value erhöht am falschenOOrt

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Bykl
User
Beiträge: 92
Registriert: Donnerstag 5. Oktober 2017, 17:57

Mein Dic funktioniert falsch....

Code: Alles auswählen

code=[0, 1, 1, 0, 1, 0]
mydic={1:0,2:0,3:0}
z=0
for t in code:
    if code[t]==1 and code[t+1]==0:
        z+=1
        print("F1",code[t],code[t+1],z)
        mydic[z]=mydic[z] + 1 if key in mydic else 1
        print(mydic)
        z=0
    else:
        pass
    if code[t]==1 and code[t+1]==1:
        z+=1
        print("F2",code[t],code[t+1],z)
        mydic[z]=mydic[z] + 1 if key in mydic else 1
        print(mydic)
    else:
        pass
    if code[t]==0 and code[t+1]==1:
        z=0
        print("F3",code[t],code[t+1],z)
        print(mydic)
    else:
        pass
    if code[t]==0 and code[t+1]==0:
        z=0
        print("F4",code[t],code[t+1],z)
        print(mydic)
    else:
        pass
print(mydic)
{1: 2, 2: 1, 3: 0} hat er , er müsste aber {1: 1, 2: 1, 3: 0} haben....

Warum zählt er 2 Einser-Ketten, Länge 1, statt eine?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bykl: Was soll der Code denn machen? Das weiss hier ja keiner ausser Dir. Einfach zu sagen da kommt X, es sollte aber Y rauskommen und wir müssen dann raten *warum* Du denkst dass das der Fall sein soll, ist nicht wirklich zielführend.

Ist Dir klar, das in den ``if``-Bedingungen immer nur das erste und das zweite oder das zweite und das dritte Element von `code` betrachtet werden? Also nie ein Element mit einem Index > 2? Falls das überraschen kommt, hätten vielleicht sinnvolle Namen geholfen das früher zu erkennen.

Die ganzen ``else: pass`` sind überflüssig und sollten weg, und statt der sich Gegenseitig ausschlissenden ``if``\s wäre das besser eine ``if``/``elif``/…-Abfolge. Am besten mit einem abschliessenden ``else`` das einen Fehler auslöst, weil der Fall nicht vorkommen darf.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Bykl
User
Beiträge: 92
Registriert: Donnerstag 5. Oktober 2017, 17:57

Hallo Blackjack,

Danke, dass Du antwortest! Der Code soll die Einserketten zählen. Einserketten sind Folgen von Einsen im Code. Er soll zählen, wie lang sie sind, und die Längen in Dictionary ablegen: Hier müsste rauskommen. 1 Kette Länge 1, eine Kette Länge 2, O Ketten Länge 3... das mit Elif hab ich gemacht, aber der Fehler ist nicht nicht weg....
Bykl
User
Beiträge: 92
Registriert: Donnerstag 5. Oktober 2017, 17:57

__blackjack__ hat geschrieben: Montag 21. November 2022, 20:32 Ist Dir klar, das in den ``if``-Bedingungen immer nur das erste und das zweite oder das zweite und das dritte Element von `code` betrachtet werden? Also nie ein Element mit einem Index > 2? Falls das überraschen kommt, hätten vielleicht sinnvolle Namen geholfen das früher zu erkennen.
nein, das war mir bis jetzt nicht klar, ich dachte t ändert sich immer .... hm... so ist es doch gedacht .... aber vllt denke ich falsch ...?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bykl: Was meinst Du mit „ändert sich immer“? Das hat halt in jedem Schleifendurchlauf den Wert eines Elementes aus `code`. In sofern ändert es sich schon. In `code` stehen aber nur 0en und 1en drin. Was hättest Du denn gedacht wie `t` andere Werte annehmen kann als in `code` enthalten sind, wenn die Schleife über die Elemente aus `code` geht?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Bykl
User
Beiträge: 92
Registriert: Donnerstag 5. Oktober 2017, 17:57

__blackjack__ hat geschrieben: Montag 21. November 2022, 21:10 @Bykl: Was meinst Du mit „ändert sich immer“? Das hat halt in jedem Schleifendurchlauf den Wert eines Elementes aus `code`. In sofern ändert es sich schon. In `code` stehen aber nur 0en und 1en drin. Was hättest Du denn gedacht wie `t` andere Werte annehmen kann als in `code` enthalten sind, wenn die Schleife über die Elemente aus `code` geht?
Hallo Blackjack, es soll ja erst die Einsen zählen und wenn bei code[t+1] Null ist, ist das Ende der Einserkette erreicht, und dann soll er feststellen, wie lang die Einserkette ist, was in z festgehalten, und dann ist z, der Key, ein der Value davon soll dann erhöht werden.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bykl: Du hast eine falsche Vorstellung was der Wert von `t` ist. Gib dem doch mal einen sinnvollen Namen. Und schau Dir mal die Werte an, welche die Laufvariable *tatsächlich* annimmt. Nicht was Du glaubst oder hoffst was das für Werte sind.

Es macht *sehr* selten Sinn die Elemente von einer Liste als *Index* in diese selbe Liste zu verwenden.

Mal eine kompakte Lösung:

Code: Alles auswählen

#!/usr/bin/env python3
from collections import Counter

from more_itertools import run_length


def main():
    code = [0, 1, 1, 0, 1, 0]
    length_to_count = Counter(
        length for value, length in run_length.encode(code) if value == 1
    )
    print(length_to_count)


if __name__ == "__main__":
    main()
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Bykl
User
Beiträge: 92
Registriert: Donnerstag 5. Oktober 2017, 17:57

Code: Alles auswählen

code=[0, 1, 1, 0,1,1,1,1,0]
mydic={1:0,2:0,3:0}
z=0
nr=0

for t in code:
    nr+=1
    print(nr,t)
Das ist der Ausdruck, und so stell ich mir das auch vor...
1 0
2 1
3 1
4 0
5 1
6 1
7 1
8 1
9 0

und die will ich eigentlich haben...
Es müsste anfangen mit t=0 und t+1=1, bloss das tut es nicht ...
Bykl
User
Beiträge: 92
Registriert: Donnerstag 5. Oktober 2017, 17:57

Ich danke Dir, Blackjack für das Tool, können wir trotzdem mein Denkproblem an meinem Tool beheben...

... und könntest Du mir was besseres zu Dictionary verlinken, als W3Schools hat, das ist wirklich sehr schwach dort ...
Bykl
User
Beiträge: 92
Registriert: Donnerstag 5. Oktober 2017, 17:57

Er sagt übrigens bei Spider 3,8: ModuleNotFoundError: No module named 'more_itertools' und es funzt nicht ...

wir haben also erfolgreich ein Problem durch ein anderes ersetzt..... :D eine sogenannte Substitutio problematica durchgeführt, oder besser eine problematische Substitution begangen...
Bykl
User
Beiträge: 92
Registriert: Donnerstag 5. Oktober 2017, 17:57

Das merkwürdige ist, in Jupiter läuft Dein Teil, dort kennt er offensichtlich more_Itertools, die Bibliothek, aber über Spider 5.1.5, was eigentlich moderner ist, nicht (Jupiter ist noch Python 3.8)
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bykl: Da hast Du jetzt `nr` eingeführt, das es im Original nicht gibt. Und welchen Sinn hat es ``t+1`` zu berechnen? `t` ist der jeweilige *Wert*, nicht der *Index*. Das ist doch der Fehler den Du da machst.

`more_itertools` ist ein Modul das man installieren muss. Es wird in der Dokumentation vom `itertools`-Modul in der Standardbibliothek erwähnt und enthält viele nützliche Werkzeuge für iterierbare Objekte.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Bykl
User
Beiträge: 92
Registriert: Donnerstag 5. Oktober 2017, 17:57

Morgen Blackjack,
__blackjack__ hat geschrieben: Montag 21. November 2022, 23:41 Das ist doch der Fehler den Du da machst.
Danke!

__blackjack__ hat geschrieben: Montag 21. November 2022, 23:41 Und welchen Sinn hat es ``t+1`` zu berechnen? `t` ist der jeweilige *Wert*, nicht der *Index*.
Weil er das Diktonary erst ändern bzw. befallen soll, wenn er die Länge der einserfolge durchgezählt hat, und auf die Null gestossen ist. Leider ist in code[t+1] nix drin, wenn in Wirklichkeit an der Stelle im Code eine Null ist.

Code: Alles auswählen

code=[0, 1, 1, 0,1,1,0]
mydic={1:0,2:0,3:0}
z=0

for t in code:
    if t==1:
        
        z+=1
        print("F1","t:",t,"z",z,"c[t]",code[t],"c[t+1]",code[t+1])
        if code[t+1]!=1:
            mydic[z]=mydic[z] + 1 if key in mydic else 1
            #mydic.update({z:1})
        print(mydic)
    elif t==0:
        z=0
        print("F2",t,z)
        print(mydic)
        print()
  
    else:
        pass
    
print(mydic)
so funktioniert auch das nicht.

__blackjack__ hat geschrieben: Montag 21. November 2022, 23:41 `more_itertools` ist ein Modul das man installieren muss. Es wird in der Dokumentation vom `itertools`-Modul in der Standardbibliothek erwähnt und enthält viele nützliche Werkzeuge für iterierbare Objekte.
ich such mal ein Installationsvideo, bloss auf meinem Computer scheint es zu sein, denn sonst Süd es ja in Jupyter nicht laufen....
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bykl: Auch in diesem Code verwendest Du wieder einen *Wert* als *Index*. Das macht keinen Sinn auf den Wert, der immer 0 oder 1 ist eine 1 zu addieren, und damit immer auf die Werte an den Indizes 1 und 2 zuzugreifen, was in diesem Fall in beiden Fällen den Wert 1 als Ergebnis hat.

Das ist auch nicht das ich meinte. Man muss bei meinem Vorschlag nicht per Index auf Werte zugreifen. Also wirklich gar nicht. Damit funktioniert das nicht nur bei Listen oder anderen Sequenzen, sondern bei jedem iterierbaren Objekt. Wie `more_itertools.run_length()`, was ja eigentlich das macht was Du willst, nur das nicht nur die Längen von Läufen von 1 gezählt werden, sondern auch die von 0. Beziehungsweise ganz allgemein Läufe von beliebigen Werten.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Antworten