Klammerwerte verstehen in range und len

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.
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

Hey =)

mal wieder scheitere ich an der Leseart eines codes wegen der Klammern in der Funktion ....

Code: Alles auswählen

def same_values(lst1, lst2):
    new_lst = []
    for index in range(len(lst1)):
        if lst1[index] == lst2[index]:
            new_lst.append(index)
    return new_lst
... konkret .... warum bezieht sich hier "Index" in Zeile drei auf den Index und nicht den Wert? "Index" als solches scheint nicht geschuetzt zu sein, da durch beliebiges Wort/Buchstabe ersetzbar ... wird also in range- und len-functions immer der Index angesprochen und in Listen und Funktionen im Allgemeinen immer ein Wert?

Echt schade, dass es die codecademy nicht auf deutsch gibt .... :/ ... und leider habe ich dazu auch im Tutorial nur eine Nennung ohne Erklaerung gefunden :(
Ist hier jemand dabei, der mit dabei helfen wuerde? Oder liegt mein Denkfehler ganz woanders?

lG, c.b
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@c.burkes: Ich verstehe die Frage nicht so ganz. `index` ist ein Wert und zwar wird der aus dem range`-Objekt bezogen das halt alle Zahlen von 0 bis ``len(lst1)`` liefert in diesem Beispiel. Und natürlich kann man für `index` auch jeden anderen Namen einsetzen, denn das ist eine ganz normale ``for``-Schleife. Da gibt es natürlich keine harten Vorschriften wie man die Laufvariable(n) benennen muss. Und der Name oder die Namen haben auch keinen Einfluss auf das Programmverhalten.

Mit welchen Klammern hast Du Probleme? Es gibt die ``[]`` vor der Schleife die eine literale leere Liste beschreiben. Und runde Klammern für Funktions-/Methodenaufrufe. Und eckige Klammern als Index-/Schlüsselzugriff. Da es sich hier wohl um Listen handeln soll, ist Indexzugriff wahrscheinlicher, der Code würde aber auch funktionieren wenn `lst1` und `lst2` beispielsweise Wörterbücher wären, die den passenden Inhalt hätten.

Was da steht ist: nimm die Länge von `lst1` und erstelle damit ein `range`-Objekt das von 0 bis Länge von `lst1` minus 1 geht. Und über dieses `range`-Objekt, also die Zahlen, geht dann die Schleife. Und diese Zahlenwerte eignen sich halt um sie als Index in die Liste(n) zu verwenden, was im Schleifenkörper dann auch gemacht wird.

Letztlich ist das aber „unpythonisch“ hier mit Indexwerten zu arbeiten. Dafür gibt es die `zip()`-Funktion:

Code: Alles auswählen

def same_values(iterable_a, iterable_b):
    return [a for a, b in zip(iterable_a, iterable_b) if a == b]
Hat auch den Vorteil, dass das nicht nur für Listen oder andere Sequenzen funktioniert, sondern für beliebige iterierbare Objekte. Noch flexibler wäre es wenn man keine Liste erstellt und zurück gibt, sondern auch wieder einen Iterator/Generator.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

vielleicht versuche ich es mal anders ...

was legt in einem Programm fest, ob ich in einer Liste, Woertberbuch, Funktion mit Inhalt 1, 2, 3, 4, 5 als Ergebnis 2 bekomme oder den Index 2 mit Wert 3?

Ja, ich glaube, das ist meine Frage .... welche Befehle (hier stehen eben `range´ und `len´ im Verdacht) bedienen sich des Wertes via Index?
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Ein Index hat in Python gar keine besondere Bedeutung. Jede ganze Zahl kann man als Index verwenden, also in eckige Klammern schreiben um z.B. auf eine Element einer Liste zuzugreifen.

Und `range` oder `len` hat auch nichts besonderes. `len` ist eine Funktion, die die Länge eines Objekts zurückliefert, bei dem die Eigenschaft Länge definiert ist und `range` liefert ein Range-Objekt, also ein Objekt, das, wenn man über es iteriert eine monotone Folge von Zahlen von einem Start- bis zu einem Endwert liefert.
Dass das eine in Kombination mit einer for-Schleife und einer Liste als Index verwendet werden kann, legst Du fest, indem Du es so programmierst.
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

@Sirius3 ... aber wuerde Deine Antwort nicht bedeuten, dass Python sich mit der Zeile ...

Code: Alles auswählen

for index in range(len(lst1)):
... gar nicht des Indexes bedient? Aber eben das tut er doch oder? So verstehe ich auch bj's Antwort .... :?

Also meine Laien-Lese waere hier bisher in etwa so ....

"for jedes Element aus der Reihenlaenge der Liste gilt: " und Element entspraeche dabei einem Index ..... obwohl eben eine Liste, solange man nicht tiefer graebt, einfach nur Werte beeinhaltet ....
Benutzeravatar
__blackjack__
User
Beiträge: 13111
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@c.burkes: In der Zeile gibt es keinen Index, also nichts was irgendwie eine besondere Eigenschaft hätte. Das ist einfach eine Schleife die über eine Reihe von Zahlen iteriert. Ganz normale Zahlen. Werte vom Typ `int`, weil dass das ist was `range()` liefert. Diese Zahlen haben kein ”Wissen” darüber wie sie entstanden sind, also weder das sie aus einem `range`-Objekt kommen, und schon gar nicht das für dieses `range`-Objekt die Länge von `lst1` beim Erstellen eine Rolle gespielt hat.

Diese Zahlen *eignen* sich natürlich sehr gut für Indexzugriffe auf `lst1` wenn das eine Sequenz ist, weil solche Objekte auf Zahlen von 0 bis Länge - 1 beim Indexzugriff entsprechend reagieren, das sie den in der Sequenz hinterlegten Wert liefern und für alle Indexwerte von 0 bis Länge - 1 definierte Werte haben (sollten).

Wobei es an der Stelle schon etwas schwammig wird, weil ”hinterlegt” ja auch bedeuten kann, das der Wert zum Index beim Zugriff berechnet, aus einer Datenbank geholt, oder sonst wie zustande kommt. `range`-Objekte selbst sind ja auch Sequenzen, also haben eine Länge und reagieren auf Indexzugriffe mit Zahlen, und `range`-Objekte speichern nicht die ganzen Zahlen, sondern berechnen die Werte beim Zugriff.

Was also bei ``some_object[some_int_value]`` dann tatsächlich passiert, bestimmt der Typ von `some_object` also letztendlich der Programmierer der diesen Typ implementiert hat. Man kann ja auch eigene Datentypen erfinden/schreiben, die auf den Schlüssel-/Indexzugriff mit eckigen Klammern reagieren.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Möglichst einfach ausgedrückt:

range(zahl) liefert dir eine Liste von Zahlen, von 0 bis zahl -1, über die du iterieren kannst.

(Das ist technisch nicht ganz korrekt, wird sich für dich aber so anfühlen)

Code: Alles auswählen

for z in range(10):
	print(z)

	
0
1
2
3
4
5
6
7
8
9
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

@sparrow ... stimmt, an diesem Beispiel, welches mir aus Tutorials bekannt ist, haette ich schon schlussfolgern koennen, dass range keine Indexe ausgibt. Danke fuers ind Gedaechtnis rufen :)


Ich haette natuerlich auch den ganzen Code angeben soll. Haette Euch vermutlich einiges an Denkarbeit erspart. Sry.

Code: Alles auswählen

def same_values(lst1, lst2):
    new_lst = []
    for index in range(len(lst1)):
        if lst1[index] == lst2[index]:
            new_lst.append(index)
    return new_lst
    

Code: Alles auswählen

print(same_values([5, 1, -10, 3, 3], [5, 10, -10, 3, 5]))
Das Ergebnis ist (fuer Euch logisch) >>> 5, -10, 3


Und jetzt ist hier die Frage, die ich leider immer noch nicht geklaert bekomme, wie ist das zu lesen. Black_Jack fuehrt ja an, dass "for index in range(len(lst1)):" keinen Index ausgibt. Dann wuerde ich die Zeile jetzt in etwa wie folgt lesen: Fuer jede einzelne Zahl in der vollen Reihenlaenge der Liste gilt: .... also sind hier wohl die Zahlen 5, 1, -10, 3 und nochmals die 3 gemeint.

In der Folgezeile wuerde doch dann aber mittels eckiger Klammern, die jeweilige gewonnene Zahl doch als Index verwendet werden, oder? also lst1[Zahl 5] = ??; lst1[Zahl 1] = 1; lst1[Zahl -10] = ??; lst1[Zahl 3] = 3 ... ich sehe halt auch, dass der Inhalt einer Liste in eckigen Klammern geschrieben werden kann. Lasse ich mich nur etwa nur vom Wort index verwirren? Mir was bisher auch nicht bekannt, dass man auf Objekte einer Liste direkt, ohne Index zugreiffen kann. Macht die Sache fuer mich gerade auch nicht einfacher xD

Tut mir echt leid, dass ich mein Problem nicht besser schildern kann. Ich verliere zwischendurch selbst immer wieder die Orientierung. Aber irgendwo in diesem Themenfeld liegt ein Stein, ueber den ich immer und immer wieder stolpere .... daher haette ich den echt gerne aus dem Weg

THX =))
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Probier es aus und schau ob das, was herauskommt dem entspricht was du erwartest.
und für deinen ersten Absatz bedeutet das:

Code: Alles auswählen

for index in range(len([5, 1, -10, 3, 3])):
	print(index)

	
0
1
2
3
4
Also nicht die Zahlen aus der Liste, sondern die Zahlen von 0 bis Länge Liste - 1.
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

AHAAAAAAAAAAAAAAAAAAAAAA =))

Das war das fehlende Ding!! Diesen Zwischenschritt hatte ich in der Vergangenheit bei einem Lernprojekt auch mal gemacht (eher zufaellig x`D) steht jetzt aber ganz oben auf der Problemloeseliste.

So ergibt das ganze jetzt wieder Sinn.

Ui =D VIELEN DANK euch beiden!! =))
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

:v: hey,

jetzt habe ich es endlich geschafft, weiter mit Klammern in der Funktion zu arbeiten, auch wenn es diesesmal nicht um range oder len geht .... was ich jetzt .... btw .... grob verstanden hab =))

verstehe ich den folgenden code ...

Code: Alles auswählen

def repeat_stuff(stuff, num_repeats=10):
    return stuff * num_repeats
print(repeat_stuff("Row ", 3))
print()
lyrics = repeat_stuff("Row ", 3) + "Your Boat. "
print(lyrics)
print()
song = repeat_stuff(lyrics)
print(song)

Code: Alles auswählen

>>> Row Row Row 

>>> Row Row Row Your Boat. 

>>> Row Row Row Your Boat. Row Row Row Your Boat. 
    Row Row Row Your Boat. Row Row Row Your Boat. 
    Row Row Row Your Boat. Row Row Row Your Boat. 
    Row Row Row Your Boat. Row Row Row Your Boat. 
    Row Row Row Your Boat. Row Row Row Your Boat.
... richtig, dass ...

Code: Alles auswählen

print(repeat_stuff("Row ", 3))
... die angegebenen Inhalte der Funktion (stuff, num_repeats=10), also auch den default-value, ueberschreibt? Dass dann die neu eingerichtete Variable ....

Code: Alles auswählen

lyrics = repeat_stuff("Row ", 3) + "Your Boat. "
... weiter mit dem ueberschriebenen Werten + string arbeitet ... und ...

Code: Alles auswählen

song = repeat_stuff(lyrics)
die Variable `song´ deshalb soviel output produziert, weil hiermit nur das argument `stuff´ ueberschrieben wird (also mit der gesamten Liedzeile), waehrend `num_repeats´ nun tatsaechlich mit dem default-value arbeitet?


Waer echt schoen, wenn dem so waer x``D - sonst brauch ich nen Motivationstrainer xD

lG!! c.b.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@c.burkes: ehrlich gesagt, verstehe ich nicht ganz, was Du geschrieben hast, aber ja, wenn kein Wert für einen Parameter einer Funktion übergeben wird, dann wird der Defaultwert genommen.
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

und sonst ist der ungeschuetzt und kann(/wird in den ersten beiden Beispielen,) jederzeit ueberschrieben werden?
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@c.burkes: Defaultwerte sind dazu da, dass sie überschrieben werden können. Was meinst Du mit "ungeschützt"? "Jederzeit" ist auch das falsche Adjektiv; der Defaultwert wird überschrieben, wenn DU den Funktionsaufruf genau so programmierst.
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

Sirius3 hat geschrieben: Montag 4. März 2019, 16:37 wenn DU den Funktionsaufruf genau so programmierst.
und das tue ich im call der Funktion (siehe erstes und zweites Beispiel)?
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

genau.
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

\(*-*)/ :thumbsup: und thx :D
Benutzeravatar
Perlchamp
User
Beiträge: 172
Registriert: Samstag 15. April 2017, 17:58

@ c.burkes:
ich habe die Funktion mal eingedeutscht, vielleicht wird's dann etwas verständlicher:

Code: Alles auswählen

def multipliziere_irgendwas(irgendwas, anzahl=10):
	return irgendwas * anzahl
du übergibst der Funktion MINDESTENS ein Objekt. Dies kann beispielsweise eine Zeichenkette, eine Zahl oder auch ein *Ausdruck* sein. Du kannst jedes Objekt übergeben, das mit dem Operator '*' 'arbeiten' kann.
Übergibst du eine Zeichenkette:

Code: Alles auswählen

multipliziere_irgendwas('Hallo')
dann wird diese durch Konkatenation 10 mal aneinandergehängt, da du für *anzahl* den Standardwert '10' hast, also:

Code: Alles auswählen

HalloHalloHalloHalloHalloHalloHalloHalloHalloHallo
Übergibst du nun auch ein zweites Argument (anzahl):

Code: Alles auswählen

multipliziere_irgendwas('Hallo', 3)
dann bekommst du als Ergebnis:

Code: Alles auswählen

HalloHalloHallo
weil du den Standardwert überschrieben hast.
Wenn du beispielsweise

Code: Alles auswählen

multipliziere_irgendwas(3)
bekommst du als Ergebnis 30 (3*10).
Du kannst als Argument auch einen Ausdruck übergeben, beispielsweise:

Code: Alles auswählen

ausdruck = multipliziere_irgendwas('Hallo', 3) + ' wer ist da? '
multipliziere_irgendwas(ausdruck, 3)
und bekommst dann als Ergebnis

Code: Alles auswählen

HalloHalloHallo wer ist da? HalloHalloHallo wer ist da? HalloHalloHallo wer ist da?
EDIT:
Option 'Mich benachrichtigen, ...' aktiviert
wer lesen kann ist klar im Vorteil ;-)
es gibt keine Probleme, sondern nur Lösungen !
Bildung ist die Freude auf mich selbst !
c.burkes
User
Beiträge: 58
Registriert: Montag 4. Februar 2019, 11:38

Perlchamp hat geschrieben: Montag 4. März 2019, 19:37 Übergibst du nun auch ein zweites Argument (anzahl):

Code: Alles auswählen

multipliziere_irgendwas('Hallo', 3)
dann bekommst du als Ergebnis:

Code: Alles auswählen

HalloHalloHallo
weil du den Standardwert überschrieben hast.


EDIT:
Option 'Mich benachrichtigen, ...' aktiviert

Das war der Punkt - vielen Dank fuer diese Veranschaulichung!!

Option 'Mich benachrichtigen, ...' aktiviert =>=>=> ??? =>=>=> falls Du meine Mail meinst, die ist leider ausgelaufen ... PN sollte aber funktionieren :)

Warum gibt es in diesem Forum eigentlich keine cookies, die man verteilen kann, als kleine Geste des Dankes? Waer schon Ebbe in meiner Dose ;D
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

🍪🍪🍪🍪🍪
Antworten