Python: Bestimmte Stellen im Array ändern klappt nicht.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
EXCLUZIVE
User
Beiträge: 4
Registriert: Dienstag 18. Dezember 2018, 21:46

ich habe ein kleines Problem, und zwar soll ich ein Programm schreiben was Zustände darstellt.
Erster Schritt: Es gibt 150 Kerzen, alle sind am Anfang an spricht (1)
Zweiter Schritt: Danach geht jede zweite Kerze aus.
Dritter Schritt: Danach soll jede dritte Kerze angehen.
Vierter Schritt: Danach soll jede vierte Kerze ausgehen.


Problem bei der Sache ist, als ich es versucht habe den Zweiten Schritt zu demonstrieren, hatte ich auf einmal 300 Zeichen statt 150.
Vielleicht ist einer so nett und kann mit mein Fehler erklären, danke im voraus.

Code: Alles auswählen

türen = []

for z in range (150):
    türen.append(1)
    if z+1 % 2 != 0:
        türen.append(0)
        #if z+2 %2 != 0:
           #türen.append(1)
           #if z+3 %2 != 0:
               #türen.append(0)
        
print(türen)
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Dein Problem ist, dass du die Herstellung des Anfangszustandes zusammenrührst mit dem löschen der Kerzen.

Das ist zu trennen.

Code: Alles auswählen

kerzen = [1] * 150
 
def lösche(schrittweite, kerzen):
       ...
       
for geht_aus in (2, 3, 4):
        lösche(geht_aus, kerzen)
 
EXCLUZIVE
User
Beiträge: 4
Registriert: Dienstag 18. Dezember 2018, 21:46

Habe es bisschen anders gelöst, nur muss ich jetzt raus finden wie ich es mit der dritten Stelle machen.

Code: Alles auswählen

türen = []

for z in range(150):
    türen.append(1)
    if z % 2 != 0:
        türen[z] = 0
        #if z % 3 == 0:
            #türen[z] = 1
            

print(türen)
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

der Ansatz ist zwar immer noch falsch, aber wenn du meinst 🤷🏼‍♂️

Ok, nach nochmaligem nachdenken ist das was ich behauptet habe Unfug.

Man kann das so machen wie du. Du musst halt mehrere Tests machen. Und du kannst dir auch das append so lange sparen, bist du entscheiden hast, was für eine Zahl es nun wird.
EXCLUZIVE
User
Beiträge: 4
Registriert: Dienstag 18. Dezember 2018, 21:46

Hmm okay, aber warum jetzt habe ich halt nur die 150 Zeichen ?
__deets__
User
Beiträge: 14542
Registriert: Mittwoch 14. Oktober 2015, 14:29

Verstehe die Frage nicht.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

verstehe die Frage auch nicht... weil das funktioniert doch grundsätzlich so:

Code: Alles auswählen

>>> kerzen = [True]*150
>>> kerzen
[True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
>>> for count, kerze in enumerate(kerzen):
...      if count % 2 == 0:
...           kerzen[count] = False
...
>>> kerzen
[False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True]
>>> kerzen_an = len([kerze for kerze in kerzen if kerze])
>>> kerzen_an
75
>>>
Gruß, noisefloor
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@noisefloor: Die 75 hätte ich ja mit `sum()` statt mit `len()` ermittelt, dann spart man sich das erstellen einer temporären Liste, nur um deren Länge zu bestimmen. :-)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Außerdem könnte man filter() benutzen:

Code: Alles auswählen

sum(filter(bool, kerzen))
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei das nicht nötig ist, weil `bool` von `int` abgeleitet ist und `True` den Wert 1 und `False` den Wert 0 hat.

Code: Alles auswählen

In [16]: sum([True, False, True, True])
Out[16]: 3
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ich habe das mal in BASIC auf dem C64 umgesetzt. :-)

Code: Alles auswählen

   10 dim c(149):cc=150:for i=0 to 149:c(i)=-1:next
  100 poke 53280,2:poke 53281,12:print"{clear}{light gray}{down}";spc(17);"kerzen"
  110 print spc(17);"======":print"{yellow}":for i=0 to 4
  120 print"     QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ":next:print
  200 for i=2 to 4:print"{light gray} anzahl brennende kerzen:";cc;"{left}   "
  210 print"{down} taste um jede";i;"{left}. kerze zu loeschen.{up}"
  220 get a$:if a$="" then 220
  230 print"                                       {up*3}"
  240 for j=i-1 to 149 step i:cc=cc+c(j)
  250 if c(j) then a=int(j/30):poke 55296+5+(a+4)*40+j-a*30,0
  260 c(j)=0:next:next
  300 print"{down*3}":end
Bild
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
EXCLUZIVE
User
Beiträge: 4
Registriert: Dienstag 18. Dezember 2018, 21:46

Guten Tag,

Ich habe die Aufgabe erfolgreich gelöst, leider konnte ich mich nicht früher bei den Helfern bedanken. Deswegen hier noch einmal Danke an alle.

Code: Alles auswählen

kerze = []
anzahl = []
zustand = True

for z in range(150):
    kerze.append(1)
    
for i in range (149):   
    for z in range(150):
        if z % (i+2) == 0:
            if zustand:
                kerze[z] = 0
            else:
                kerze[z] = 1
                
    zustand = not zustand
        
for z in range (150):
    if kerze[z] == 0:
        anzahl.append(z + 1)
        
print("Es wurden " +str(len(anzahl))+" Kerzen angemacht :")
print(anzahl)
print()


Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

@EXCLUZIVE: ›anzahl‹ wird im Skript viel zu früh initialisiert. Variablen immer erst dann initialisieren, wenn sie auch gebraucht werden, also erst vor der letzten for-Schleife. ›anzahl‹ ist auch eine seltsamer Name für eine Liste, die die Indizes + 1 der Kerzen enthält, die aus sind. Damit ist auch die Lösung falsch und nur zufällig richtig, weil gleich viele Kerzen aus wie an sind.

An und Aus werden üblicherweise über Wahrheitswerte True und False repräsentiert, nicht 1 und 0. Wenn man berücksichtigt und ›zustand‹ an der richtigen Stelle ändert, dann braucht man die innere if-Abfrage gar nicht, sondern kann ›zustand‹ gleich ›kerze[z]‹ zuweisen:

Code: Alles auswählen

kerze = []
for z in range(150):
    kerze.append(True)
    
zustand = True
for i in range (149):   
    zustand = not zustand
    for z in range(150):
        if z % (i+2) == 0:
            kerze[z] = zustand

indices = []
for z in range (150):
    if kerze[z]:
        indices.append(z + 1)
print("Es wurden {} Kerzen angemacht :".format(len(indices)))
print(indices)
print()
Nun ist es unüblich, über Indizes zu iterieren, wenn man auch über die Listenelemente direkt iterieren könnte, wenn man trotzdem einen Index braucht, nimmt man enumerate. Das hat den Vorzeil, dass man nicht mehr wissen muß, wie viele Elemente die Liste hat.
Statt Listen zu ändern, erzeugt man neue Listen:

Code: Alles auswählen

kerzen = [True] * 150
    
zustand = True
for i in range(2, len(kerzen) + 1):   
    zustand = not zustand
    kerzen_alt = kerzen
    kerzen = []
    for z, kerze in enumerate(kerzen_alt):
        kerzen.append(zustand if z % i == 0 else kerze)

indices = []
for z, kerze in enumerate(kerzen, 1):
    if kerze:
        indices.append(z)
print("Es wurden {} Kerzen angemacht :".format(len(indices)))
print(indices)
print()
Nun kann man die Schleifen noch durch Listecomprehensions ersetzen:

Code: Alles auswählen

kerzen = [True] * 150
    
zustand = True
for i in range(2, len(kerzen) + 1):   
    zustand = not zustand
    kerzen = [
        zustand if z % i == 0 else kerze
        for z, kerze in enumerate(kerzen)
    ]

indices = [z for z, kerze in enumerate(kerzen, 1) if kerze]
print("Es wurden {} Kerzen angemacht :".format(len(indices)))
print(indices)
print()
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Upsi, ich hatte das abwechselnd an- und ausmachen glatt überlesen. Auch wenn es keinem aufgefallen ist, hier die korrigierte CBM BASIC Variante:

Code: Alles auswählen

    1 rem@ £protocol:£fastfor:£shortif:£fastarray
    2 rem@ £byte a=fast,cc=fast,i,j=fast,z=fast,c(,cl(
   10 dim c(149),t$(1),cl(1):t$(0)="loeschen":t$(1)="entzuenden"
   20 cl(0)=0:cl(1)=7:z=1
  100 poke 53280,2:poke 53281,12
  110 print"{clear}{light gray}{down}";spc(15);"kerzen v2"
  120 print spc(15);"=========":print:for i=0 to 4
  130 print"     QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ":next:print
  200 for i=1 to 4:for j=i-1 to 149 step i:c(j)=z:a=int(j/30)
  210 poke 55296+5+(a+4)*40+j-a*30,cl(c(j)):next:z=abs(1-z)
  220 cc=0:for j=0 to 149:cc=cc+c(j):next
  230 print"{light gray} anzahl brennende kerzen:";cc;"{left}   "
  240 if i=4 then 270
  250 print"{down} taste um jede";i+1;"{left}. kerze zu ";t$(z);".{up}"
  260 get a$:if a$="" then 260
  270 print"                                       {up*3}":next
  300 print"{down*3}":end
Bild
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten