Verschachtelte for - Schleife

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
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

Hi Leute,

und zwar geht es um diesen Code:

Code: Alles auswählen

test = [1,2,3,4]
for i in range(len(test)): # -> 0, 1, 2, 3
            for j in range(i + 1, len(test)): #  -> 1, 2, 3
                print('hier',  j)
Bei einer verschachtelten for Schleife wird ja die Anzahl der Iterationen von der Anzahl der äußeren Schleife bestimmt, richtig?

Beispiel:

Code: Alles auswählen

for i in range(2):
     print(i)
     for j in range(10,13):
          print(j)
Hier wird die Anzahl der Iterationen durch die Äußere Schleife for i in range(2) auf zwei festgelegt. Bei dem ersten Durchgang mit null startet die innere Schleife for j in range(10,13) ihren kompletten Durchgang - also führt alle seine Iterationen aus. usw.

Weshalb ist dann die Ausgabe vom ersten Codebeispiel nicht:


1
2
3

2
3
4

4
5
6

5
6
7


Danke fürs Antworten/Hilfe!
Benutzeravatar
grubenfox
User
Beiträge: 431
Registriert: Freitag 2. Dezember 2022, 15:49

bei der inneren Schleife ist der Endwert

Code: Alles auswählen

len(test)
bzw. 4. Damit endet die innere Schleife immer bei der 3
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Das liegt daran, dass sich in der inneren Schleife mit zunehmendem Wert für i die Zahl der Schleifendurchläufe reduziert. Die obere Grenze von range ist bei dir konstant.
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

Also die Ausgabe lautet ja:

Code: Alles auswählen

hier 1
hier 2
hier 3
hier 2
hier 3
hier 3
Wie genau läuft das ab? Vor allem wundert mich dieser Part:

hier 2
hier 3
hier 3
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@norgsmen: Warum wundert Sich das? `i` wird immer grösser, womit die untere Grenze immer grösser wird, und die obere Grenze ändert sich nie. Was hättest Du da denn erwartet und warum?

Das erste Beispiel lässt sich ja vereinfachen weil ``len(test)`` bekannt und fix ist:

Code: Alles auswählen

for i in range(4):  # -> 0, 1, 2, 3
    print("-", i)
    for j in range(i + 1, 4):
        print('hier', j)
Den Kommentar bei der inneren Schleife habe ich mal nicht übernommen, denn der stimmt ja gar nicht immer, sondern nur beim ersten Durchlauf der äusseren Schleife.

Falls das am Ende dazu benutzt werden soll paarweise verschiedene Elemente aus `test` zu nehmen um damit irgend etwas zu machen, dann kann man auch einfach das hier nehmen:

Code: Alles auswählen

In [33]: for pair in itertools.combinations([1, 2, 3, 4], 2):
    ...:     print(pair)
    ...: 
(1, 2)
(1, 3)
(1, 4)
(2, 3)
(2, 4)
(3, 4)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

norgsmen hat geschrieben: Donnerstag 16. März 2023, 14:34 Wie genau läuft das ab? Vor allem wundert mich dieser Part:
Dann lass dir mal die Werte von "i + 1" und "len(test)" ausgeben, bevor du diese Zeile erreichst:

Code: Alles auswählen

for j in range(i + 1, len(test)): #  -> 1, 2, 3
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

@__blackjack__ Was genau meinst du mit untere bzw. obere Grenze?

Also mir ist
1. nicht verständlich wie es zu sechs ausgaben, kommt?

Code: Alles auswählen

for i in range(len(test)): # -> 0, 1, 2, 3
Hier wird doch angegeben das die Iterationen viermal durchgeführt werden sollen. Müsste die Ausgabe dementsprechend auch nicht vier sein?

2. wegen des

Code: Alles auswählen

i + 1
startet er ja mit dem Wert 1 (hier 1) und endet dann bei hier 3 da die Ausgabe 0, 1, 2, 3 beträgt (ist das soweit korrekt?) wo kommt aber dann das hier her:

hier 2
hier 3
hier 3


Danke an alle:D
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@norgsmen: `range()` hat zwei Grenzen, eine untere, wo angefangen wird zu zählen, und eine obere, die bestimmt wie weit gezählt wird.

Die äussere Schleife wird viermal durchlaufen und jedes mal gibt es dann ja *innen* eine weitere Schleife die ja auch mehrfach, in Abhängigkeit von `i`, durchlaufen wird und *dort* werden die Ausgaben gemacht, also sind es mehr als vier Ausgaben.

``i+1`` bedeutet nicht das bei 1 gestartet wird, sondern das bei `i+1` gestartet wird. Ja, wenn `i` den Wert 0 hat, dann ist das 1, aber `i` hat ja nicht fest den Wert 0 sondern bei jedem äusseren Schleifendurchlauf einen anderen Wert. Und genau da kommen die Ausgaben her.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

Andere Beispiele wie z.B

Code: Alles auswählen

num_list = [1, 2, 3]
alpha_list = ['a', 'b', 'c']

for number in num_list:
    print(number)
    for letter in alpha_list:
        print(letter)
sind leicht zu verstehen, aber bei dem Code:

Code: Alles auswählen

test = [1,2,3,4]
for i in range(len(test)): # -> 0, 1, 2, 3
            for j in range(i + 1, len(test)): #  -> 1, 2, 3
                print('hier',  i, j)
verstehe ich leider die Ausgabe einfach überhaupt nicht. Falls jemand die Ausgabe mit einem Beispiel durchlauf erklären kann, wäre ich super dankbar!

Ich habe auch mal i mit ausgegeben und da kommt das raus:


hier 0
hier 0
hier 0
hier 1
hier 1
hier 2


Aber auch hier habe ich absolut keine Ahnung wie das Zustande kommt
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@norgsmen: Was genau verstehst Du denn daran nicht? `i` ist halt nicht fest sondern in jedem Durchlauf der äusseren Schleife anders, weshalb die innere Schleife nicht immer zur gleichen Anzahl von Schleifendurchläufen führt. Wenn Du das nicht verstanden hast, dann hast Du einzelne Schleifen oder auch das andere, angeblich leicht zu verstehende Beispiel, auch nicht verstanden.

Der Kommentar ``# -> 1, 2, 3`` ist falsch, weil der nur für einen von vier äusseren Schleifendurchläufen stimmt.

Erklär *Du* doch mal wie das Deiner Meinung nach ablaufen sollte, und warum. Schritt für Schritt. Und lass Dir die Werte ausgeben. Und dann siehst Du ja an welcher Stelle das Programm nicht das macht, was Du erwartest.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast eine innere Schleife, deren Anzahl an Durchläufen variabel ist, und zwar abhängig von der Variable der äußeren Schleife

Code: Alles auswählen

for i in range(4):
    print(f"i={i}, deshalb läuft die innere Schleife von {i+1} bis 3")
    for j in range(i + 1, 4):
        print('hier', i, j)
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Wenn man bei deinem Code die äußere Schleife weglässt und die Aufrufe der inneren Schleife dann einzeln hinschreibt, dann bekommt man so etwas:

Code: Alles auswählen

for j in range(1, 4):
    print('hier', j)
for j in range(2, 4):
    print('hier', j)
for j in range(3, 4):
    print('hier', j)
for j in range(4, 4):
    print('hier', j)
Jetzt klarer?
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

@/me

Den ersten Teil also die Äußere for Schleife ist verständlich

Code: Alles auswählen

for i in range(len(test))
dort läuft er bis exkusiv 4 durch, also --> 0, 1, 2, 3

Allerdings ist mir immer noch nicht verständlich, wie es dabei zu sechs Output Ausgaben kommt und vor allem zu dieser Zahlenreihe:


hier 1
hier 2
hier 3
hier 2
hier 3
hier 3


Kann jemand bitte ein Beispiel Durchlauf vormachen? Danke!
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

norgsmen hat geschrieben: Freitag 17. März 2023, 08:38 Kann jemand bitte ein Beispiel Durchlauf vormachen? Danke!
Davon gab es bislang bereits mehrere. Was Du jetzt tun solltest ist ein eigener Durchlauf mit Bleistift und Papier. Denn verstehen was passiert musst Du selbst, das kann Dir keiner abnehmen.
Benutzeravatar
/me
User
Beiträge: 3556
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Dein Code.

Code: Alles auswählen

test = [1, 2, 3, 4]
for i in range(len(test)):  # -> 0, 1, 2, 3
    for j in range(i + 1, len(test)):
        print('hier', j)

`test` ist fix, also könntest du das auch so schreiben.

Code: Alles auswählen

for i in range(4):  # -> 0, 1, 2, 3
    for j in range(i + 1, 4):
        print('hier', j)

Im ersten Durchlauf der äußeren Schleife nimmt `i` den Wert `0` an. Damit hast du dann also für diesen Durchgang wenn man das `i + 1` in der zweiten Schleife ausrechnet:

Code: Alles auswählen

    for j in range(1, 4):
        print('hier', j)
`j` läuft also von 1 bis 3 (der Wert für das Ende der Schleife ist exklusiv, aber das scheint dir ja klar zu sein).

Ausgabe:

Code: Alles auswählen

hier 1
hier 2
hier 3
Danach beginnt die nächste äußere Schleife in der `i` den Wert 1 annimmt. Für die innere Schleife rechnen wir das `i + 1` wieder aus und erhalten 2.

Code: Alles auswählen

for j in range(2, 4):
    print('hier', j)
`j` läuft also von 2 bis 3 und die Ausgabe ist folglich:

Code: Alles auswählen

hier 2
hier 3
In der nächsten äußeren Schleife wird `i` dann 2. Für die innere Schleife heißt das dann:

Code: Alles auswählen

for j in range(3, 4):
    print('hier', j)

Die Ausgabe ist

Code: Alles auswählen

hier 3
In der letzten folgenden äußeren Schleife erhält `i` den Wert 3. Und damit sieht die innere Schleife dann so aus.

Code: Alles auswählen

for j in range(4, 4):
    print('hier', j)
Von 4 bis exklusive 4 gibt es keinen Wert. Die Schleife wird folglich nicht betreten und es gibt keine Ausgabe.

Noch detaillierter geht es wirklich nicht.
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

"Das liegt daran, dass sich in der inneren Schleife mit zunehmendem Wert für i die Zahl der Schleifendurchläufe reduziert. Die obere Grenze von range ist bei dir konstant."

Ich hab es gerafft! Danke an alle für die Hilfestellung(en) bis zum nächsten mal:D

//close
Benutzeravatar
Kebap
User
Beiträge: 687
Registriert: Dienstag 15. November 2011, 14:20
Wohnort: Dortmund

Dafür schuldest du uns aber was :D
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
norgsmen
User
Beiträge: 55
Registriert: Samstag 26. Juni 2021, 22:09

:D :lol:
Antworten