andie39‘s Fragen Thread

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
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Da ich bei meinen Onlineübungen doch immer wieder einmal Fragen habe und nicht das Forum vollspammen möchte, mache ich diesen Thread auf in dem ich meine aktuellen Fragen poste.

Ich denke das ist besser als lauter Fragen in einzelnen Threads. Hoffe ich zumindest.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Frage 1:

Folgende Aufgabe hatte ich gehabt:

Aufgabe:

c.) Schreibe eine Funktion, die die Listen mit den Artikeln auffüllt!
Von nun an soll auch eine Funktion die Waren in die virtuellen Regale einräumen, d. h. an die erste, noch leere Position in der Liste shelf packen. Als Parameter soll der Funktion add_shelf() der einzusortierende Artikel übergeben werden. Die Funktion aktualisiert dann die Liste shelf, und der neue Artikel wurde in das erste leere Regalfach eingeräumt.

Code: Alles auswählen

shelf = ["Zaubersäge", "leer", "Wunderkekse", "Trickkarten", "leer"]

def add_shelf(article):
    for i in range(0, len(shelf)):
        if shelf[i] == "leer":
            shelf[i] = article
            break
    
add_shelf("Rubik's Cube")
print(shelf)


Der Code hier ist die „Musterlösung“.


Dazu folgendes:
Die range Funktion die ja einen Zahlenbereich abdeckt:

Ich hätte das hier eher so erwartet:

Code: Alles auswählen


shelf = ["Zaubersäge", "leer", "Wunderkekse", "Trickkarten", "leer"]

def add_shelf(article):
    for i in shelf:
        if shelf[i] == "leer":
            shelf[i] = article
            break
    
add_shelf("Rubik's Cube")
print(shelf)

Das für jeden Wert „i“ in der Liste shelf geprüft wird ob der Wert „leer“ ist und falls ja diesen durch den Wert „article“ ersetzt.


Das gibt aber den Fehler:
list indices must be integers or slices, not str


In der Musterlösung geht die for schleife alle Positionen durch von 1 „0“ bis zur Länge der liste, also die Anzahl der durch Komma getrennten Bereiche.

Aber warum geht das nicht bei for i in shelf?
Warum genau geht er hier nicht jede Nummer in shelf durch und prüft diese?
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du gehst in Abweichung zur musterlösung die WERTE durch. Nicht die Indizes. Aber behandelst die dann, als ob sie Indizes wären . Darum die Fehlermeldung. Die Position „leer“ kennt eine Liste nicht. Positionen sind immer zahlen.


Dies hier (durch das Update der Liste) ist einer der Fälle, wo man eben Index-basiert arbeiten kann.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Das verstehe ich nicht.
Du sagst ich durchsuche die Werte und behandele diese dann als ob sie Werte wären.

Sie sind doch Werte…..

In der Musterlösung werden doch die Indizierungen durchlaufen und wenn diese einen bestimmten Wert haben wird dieser ersetzt oder nicht?

Warum ist das bei for i in shelf nicht so? Ich hätte erwartet das das auch hier der Fall ist.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@andie39: Nein, Du behandelst die Werte als ob sie Indizes wären. Lass Dir doch mal `i` in Deinem Beispiel ausgeben. Und was soll dann ``shelf[ i ]`` bedeuten?

Warum hättest Du bei bei ``for i in shelf:`` erwartet, dass das Indexwerte sind? Das ist nicht so weil das nicht so ist. Ich weiss nicht was man da sonst zu sagen soll. So sind Listen implementiert und dokumentiert ist das auch so, das iterieren über eine Liste = iterieren über die Elemente der Liste ist. Macht auch mehr Sinn als über die Indexwerte zu iterieren, denn dann müsste man ja immer diesen in 99% der Fälle unnötigen Indexzugriff machen, um an dann an das Element zu kommen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Ich glaube das ich die for-schleife, iterieren und index nicht richtig verstanden habe.

Indexierung ist doch die Stelle mit einer Zahl.
Bei Strings sind das die Buchstaben.
In der Liste die getrennten Abschnitte wenn man so will.

Im Fall einer csv Datei wie: for line in datei.csv
sind ja die Zeilen indexiert und zwar weil es so ist und nicht weil for LINE geschrieben wird.

Hier ist es ja eine Liste die indexiert ist und diese sind mit Komma getrennt.
….

und während ich das schreibe und nochmal auf mein Post hin und her schaue GLAUBE ich, hab ich es doch verstanden.

i nimmt einfach nur eine indexposition an.
Von „1“ bis Gesamtzahl der Positionen von shelf
Erst die if Funktion geht dann die Positionen durch.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

__blackjack__ hat geschrieben: Sonntag 9. Januar 2022, 01:13 @andie39: Nein, Du behandelst die Werte als ob sie Indizes wären. Lass Dir doch mal `i` in Deinem Beispiel ausgeben. Und was soll dann ``shelf[ i ]`` bedeuten?
Ja logisch
Bei mir wäre der Wert z.B „Säge“ ein Indexpunkt.
Was nicht geht sondern eine ganze Zahl sein muss
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Man kann sich den Index wie einen Lagerplatz vorstellen. Das Element Säge liegt zB auf Platz 3. Wenn man also fragt, was auf Platz xy liegt, dann erhält man das passende Element als Wert.

Bei einer for-Schleife über eine (Lager-)Liste erhält man nicht alle Lagerplätze, sondern die darauf befindlichen Gegenstände, mit denen man direkt hantieren kann. Sie werden somit nicht über ihren Lagerplatz angesprochen, sondern unmittelbar. Das sollte man sich schon klar machen.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Also hier wird ja jeder Lagerplatz durchgegangen und wenn ein Platz den Wert „leer“ hat wird dieser ersetzt und die Schleife gestoppt.

Von daher habe ich nochmal geschaut und hätte gedacht das es auch so geht:

Code: Alles auswählen

shelf = ["Zaubersäge", "leer", "Wunderkekse", "Trickkarten", "leer"]

def add_shelf(article):
    for i in shelf:
        if i == "leer":
            i = article
            break
    
add_shelf("Rubik's Cube")
print(shelf)


Aber das ist nicht der Fall.
So ganz ist es mir doch nicht klar….

Sehr kompliziert
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Es gibt kein magisches Update aller Verweise. Das wäre ausgesprochen unpraktisch.

Du bindest jeweils ein Element aus der Liste shelf an den Namen "i". Dann schaust du, ob der Wert von i gleich der Zeichenkette "leer" ist. Wenn dem so ist, bindesr du das, was ab article gebunden ist an i. Das heißt aber nicht, dass da etwas in der shelf geändert wird.

Code: Alles auswählen

a="foo"
b=a
b="ham"
Hiet würdest du doch auch nicht erwarten, dass a sich ändert, oder?
Falls doch: So funktioniert Referenzierung in Python nicht.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

sparrow hat geschrieben: Sonntag 9. Januar 2022, 10:10 Es gibt kein magisches Update aller Verweise. Das wäre ausgesprochen unpraktisch.

Du bindest jeweils ein Element aus der Liste shelf an den Namen "i". Dann schaust du, ob der Wert von i gleich der Zeichenkette "leer" ist. Wenn dem so ist, bindesr du das, was ab article gebunden ist an i. Das heißt aber nicht, dass da etwas in der shelf geändert wird.

Code: Alles auswählen

a="foo"
b=a
b="ham"
Hiet würdest du doch auch nicht erwarten, dass a sich ändert, oder?
Falls doch: So funktioniert Referenzierung in Python nicht.
Grundsätzlich ja aber hier wird es doch geändert:

Code: Alles auswählen


shelf = ["Zaubersäge", "leer", "Wunderkekse", "Trickkarten", "leer"]

def add_shelf(article):
    for i in range(0, len(shelf)):
        if shelf[i] == "leer":
            shelf[i] = article
            break
    
add_shelf("Rubik's Cube")
print(shelf)

__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja. Da wird doch explizit das I-te Element in der Liste auf der linken Seite als Ziel der Änderung benannt.
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Ja. Aber bei der anderen Variante doch auch oder nicht?
Sobald ein i-Element „leer“ wird, wird das geändert.
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Nein.
Zeig mal wo das bei der anderen Variante geändert wird. Wo steht da "Ändere etwas in der Liste"?
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

sparrow hat geschrieben: Sonntag 9. Januar 2022, 11:13 Nein.
Zeig mal wo das bei der anderen Variante geändert wird. Wo steht da "Ändere etwas in der Liste"?

if i == "leer":
i = article
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wo steht denn da die Liste? Ich sehe da nichts von shelf.
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Da steht "wenn der Wert, der an i gebunden ist, gleich der Zeichenkette 'leer' ist, dann binde den Wert, der an article gebunden ist zusätzlich an den Namen i".
Und wo genau ist da jetzt irgend eine Liste, deren Werte sich ändern sollen?
Benutzeravatar
andie39
User
Beiträge: 152
Registriert: Dienstag 7. Dezember 2021, 16:32

Jetzt hat es klick gemacht……. Danke für die Geduld.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

andie39 hat geschrieben: Sonntag 9. Januar 2022, 11:14
sparrow hat geschrieben: Sonntag 9. Januar 2022, 11:13 Nein.
Zeig mal wo das bei der anderen Variante geändert wird. Wo steht da "Ändere etwas in der Liste"?

if i == "leer":
i = article
Stell dir "i" wie einen Zettel vor. Auf diesen Zettel wird in deiner Schleife immer der aktuelle Wert aus der Liste geschrieben. Der Zettel hat aber keine Rückverbindung zur Liste. Schreibst du etwas anderes auf den Zettel, dann beeinflusst das deine Liste so rein gar nicht.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Die Musterlösung sollte aus meiner Sicht einen besseren Funktionsnamen haben, "shelf" als Parameter erhalten und statt "range(0, len(shelf))" "enumerate" verwenden. Noch eleganter geht es mit der List-Methode "index" sowie einem Rückgabewert, der die Position des neuen Elements angibt oder einen anderen Wert hat, falls im Regal kein Platz mehr frei war.

@andie39: Wenn Du magst, versuche zur Übung die Aufgabe mit "enumerate" zu lösen und dann später auch noch den oben genannten Rückgabewert zu liefern.
Antworten