Werte werden von einer Schleife nicht in eine andere Schleife übernommen

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
Bill987654321
User
Beiträge: 136
Registriert: Sonntag 8. März 2020, 10:56

Habe mein Programm weitergeschrieben. Leider funktioniert es nicht.

Code: Alles auswählen

#!/usr/bin/env python3

MANNSCHAFTSANZAHL = 4 #gross geschrieben, weil Konstante
MANNSCHAFTSNAMEN_DATEINAME = "Mannschaftsnamen.txt" #alles groß geschrieben, weil Konstante

mannschaftsnamen = [] #generieren einer Liste
for i in range(1, MANNSCHAFTSANZAHL + 1):
    mannschaftsname = input(f"Gebe den Namen der {i}. Mannschaft ein: ") #Eingabe der Mannschaften
    print(f"Die {i}. Mannschaft ist {mannschaftsname}.")
    print("Die {i}. Mannschaft ist {mannschaftsname}.") #format ohne f
    mannschaftsnamen.append(mannschaftsname) #mannschaftsname wird an mannschaftsname angehängt
    print(i)
    print(type(i))
    print(mannschaftsname)
    print(mannschaftsnamen, "mannschaftsnamen")
    print("Leerzeile")

with open(MANNSCHAFTSNAMEN_DATEINAME, "w", encoding="utf-8") as output: #file zum Schreiben wird geöffnet
    for mannschaftsname in mannschaftsnamen:
        output.write(f"{mannschaftsname}\n")

mannschaftsnamen = [] #generieren einer Liste
with open(MANNSCHAFTSNAMEN_DATEINAME, encoding="utf-8") as lines: #file zum Lesen wird geöffnet
    for line in lines:
        mannschaftsnamen.append(line.rstrip())
print("Auslesen aus Datei vollendet*******************************\n\n")

print("Erste Zeile ((mannschaftsnamen),('mannschaftsnamen'))")
print((mannschaftsnamen),("mannschaftsnamen\n"))
print("Zweite Zeile (mannschaftsnamen)")
print((mannschaftsnamen),"\n")
print("Dritte Zeile (mannschaftsname)")
print(mannschaftsname)
print("\n\n")

print("Schleifenbeginn")
for mannschaftsname in mannschaftsnamen:
    print("(mannschaftsname,[mannschaftsnamen])")
    print(mannschaftsname,[mannschaftsnamen])
    print("mannschaftsname")
    print(mannschaftsname)
print("Schleifenende")


mannschaftsnamenalphabet=mannschaftsnamen #liste mannschaftsnamenalphabet wrid angelegt
mannschaftsnamenalphabet.sort() #mannschaftsnamenalphabet wird alphabetisch sortiert
print("mannschaftsnamenalphabet wird angezeigt. Dies ist die Liste der alphabetisch sortierten Mannschaftsnamen")
print(mannschaftsnamenalphabet)
print("\n")

kopiemanaalphabet=mannschaftsnamenalphabet # kopie der liste mannschaftsnamenalphabet wird angelegt
print ("kopiemanaplphabet",kopiemanaalphabet)
print("\n")

i=0
nummer_und_mannschaftsname=[]
for mannschaftsname in kopiemanaalphabet:
    i=i+1
    print("Nummer der Mannschaft i=",i)
    print(mannschaftsname)
    nummer_und_mannschaftsname=[i,mannschaftsname]
    print((nummer_und_mannschaftsname),"nummer_und_mannschaftsname XXXXXXXXXX") #mannschaftsnummer_und_mannschaftsname wird angezeigt
    print("i=",i)
    print("str(i)=",str(i))
    print("\n")


for mannschaftsname in kopiemanaalphabet:
    print((nummer_und_mannschaftsname),"nummer_und_mannschaftsname YYYYYYYYYY")
In der Zeile mir den vielen X zeigt Python die Liste korrekt an. In der Zeile mit den vielen Y werden 4 mal die Werte des letzten Datensatzes angezeigt, obwohl sich die Zeile in einer for Schleife befindet (siehe unten).
Warum ist das so?

Hier der Bildschirmausdruck:

Python 3.8.2 (tags/v3.8.2:7b3ab59, Feb 25 2020, 22:45:29) [MSC v.1916 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license()" for more information.
>>>
========= RESTART: C:/Users/pc/Desktop/Python Programme/Code für dpf.py ========
Gebe den Namen der 1. Mannschaft ein: Dortmund
Die 1. Mannschaft ist Dortmund.
Die {i}. Mannschaft ist {mannschaftsname}.
1
<class 'int'>
Dortmund
['Dortmund'] mannschaftsnamen
Leerzeile
Gebe den Namen der 2. Mannschaft ein: Augsburg
Die 2. Mannschaft ist Augsburg.
Die {i}. Mannschaft ist {mannschaftsname}.
2
<class 'int'>
Augsburg
['Dortmund', 'Augsburg'] mannschaftsnamen
Leerzeile
Gebe den Namen der 3. Mannschaft ein: Schalke
Die 3. Mannschaft ist Schalke.
Die {i}. Mannschaft ist {mannschaftsname}.
3
<class 'int'>
Schalke
['Dortmund', 'Augsburg', 'Schalke'] mannschaftsnamen
Leerzeile
Gebe den Namen der 4. Mannschaft ein: Leverkusen
Die 4. Mannschaft ist Leverkusen.
Die {i}. Mannschaft ist {mannschaftsname}.
4
<class 'int'>
Leverkusen
['Dortmund', 'Augsburg', 'Schalke', 'Leverkusen'] mannschaftsnamen
Leerzeile
Auslesen aus Datei vollendet*******************************


Erste Zeile ((mannschaftsnamen),('mannschaftsnamen'))
['Dortmund', 'Augsburg', 'Schalke', 'Leverkusen'] mannschaftsnamen

Zweite Zeile (mannschaftsnamen)
['Dortmund', 'Augsburg', 'Schalke', 'Leverkusen']

Dritte Zeile (mannschaftsname)
Leverkusen



Schleifenbeginn
(mannschaftsname,[mannschaftsnamen])
Dortmund [['Dortmund', 'Augsburg', 'Schalke', 'Leverkusen']]
mannschaftsname
Dortmund
(mannschaftsname,[mannschaftsnamen])
Augsburg [['Dortmund', 'Augsburg', 'Schalke', 'Leverkusen']]
mannschaftsname
Augsburg
(mannschaftsname,[mannschaftsnamen])
Schalke [['Dortmund', 'Augsburg', 'Schalke', 'Leverkusen']]
mannschaftsname
Schalke
(mannschaftsname,[mannschaftsnamen])
Leverkusen [['Dortmund', 'Augsburg', 'Schalke', 'Leverkusen']]
mannschaftsname
Leverkusen
Schleifenende
mannschaftsnamenalphabet wird angezeigt. Dies ist die Liste der alphabetisch sortierten Mannschaftsnamen
['Augsburg', 'Dortmund', 'Leverkusen', 'Schalke']


kopiemanaplphabet ['Augsburg', 'Dortmund', 'Leverkusen', 'Schalke']


Nummer der Mannschaft i= 1
Augsburg
[1, 'Augsburg'] nummer_und_mannschaftsname XXXXXXXXXX
i= 1
str(i)= 1


Nummer der Mannschaft i= 2
Dortmund
[2, 'Dortmund'] nummer_und_mannschaftsname XXXXXXXXXX
i= 2
str(i)= 2


Nummer der Mannschaft i= 3
Leverkusen
[3, 'Leverkusen'] nummer_und_mannschaftsname XXXXXXXXXX
i= 3
str(i)= 3


Nummer der Mannschaft i= 4
Schalke
[4, 'Schalke'] nummer_und_mannschaftsname XXXXXXXXXX
i= 4
str(i)= 4


[4, 'Schalke'] nummer_und_mannschaftsname YYYYYYYYYY
[4, 'Schalke'] nummer_und_mannschaftsname YYYYYYYYYY
[4, 'Schalke'] nummer_und_mannschaftsname YYYYYYYYYY
[4, 'Schalke'] nummer_und_mannschaftsname YYYYYYYYYY
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

nummer_und_mannschaftsname wird in der letzten Schleife nie verändert, warum erwartest Du, dass da unterschiedliche Sachen ausgegeben werden?
Weder bei

Code: Alles auswählen

mannschaftsnamenalphabet=mannschaftsnamen #liste mannschaftsnamenalphabet wrid angelegt
noch bei

Code: Alles auswählen

kopiemanaalphabet=mannschaftsnamenalphabet # kopie der liste mannschaftsnamenalphabet wird angelegt
wird eine Kopie angelegt, sondern es handelt sich immer um die selbe Liste mannschaftsnamen, die Du auch munter veränderst (sortierst).

Die leere Liste bei `nummer_und_mannschaftsname = []` wird nie benutzt.
Wenn man einen Index zusätzlich bei einer for-Schleife braucht, gibt es enumerate.
Zuletzt geändert von Sirius3 am Montag 6. April 2020, 11:55, insgesamt 2-mal geändert.
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Du solltest jetzt beginnen deinen Code in Funktionen zu unterteilen.
Diese ganzen Debug-Print-Ausgaben im Code machen das ganze noch zusätzlich unleserlich.

Zu deinem Problem:
Was soll denn dort auch anderes passieren?
Du iterierst über "kopiemanaalphabet" (ganz schlechter Name) und bindest je Durchlauf ein Element davon an "mannschaftsname". Das heißt, alles was sich in der Schleife ändert ist das, was an "mannschaftsname" gebunden ist. Und das verwendest du im inneren der Schleife wo?

Würdest du deinen Code in Funktionen unterteilen, wäre an dieser Stelle der verwendete Name undefiniert und du würdest den Fehler sehen.
Beschäftige dich dringend mit Funktionen.

Edit: Sirius3 war schneller.
Jankie
User
Beiträge: 592
Registriert: Mittwoch 26. September 2018, 14:06

In der oberen Schleife überschreibst du nummer_und_mannschaftsname ja immer mit nummer_und_mannschaftsname=[i,mannschaftsname], da wird aber nur der letzte Wert des durchlaufes gespeichert. In der unteren Schleife iterierst du ja durch kopiemanaalphabet, aber gibst nummer_und_mannschaftsname aus.
Benutzeravatar
Bill987654321
User
Beiträge: 136
Registriert: Sonntag 8. März 2020, 10:56

Danke für die zeitnahen Antworten.
Ich wusste nicht, dass ich die Daten überschreibe. Ich dachte, dass in der Schleife die Mannschaftsnummer und der Mannschaftsname für jede der 4 Mannschaften gespeichert werden.
In anderen Programmiersprachen gibt es indizierte Variablen. In einem Programm in anderer Sprache habe ich dieses Programm schon geschrieben.
Es gab eine Schleife (for i = 1 to 18). In der Schleife hatte jede der 18 Mannschaften ihre "eigenen" Werte, wie z.B. Anzahl der Spiele AS(i) oder Anzahl der Punkte AP(i).
Gibt es sowas auch in Python?
Benutzeravatar
sparrow
User
Beiträge: 4193
Registriert: Freitag 17. April 2009, 10:28

Ich habe das doch geschrieben:
Weißt du was Funktionen sind und wie sie funktionieren?
Du möchtest nämlich wirklich Funktionen benutzen.

Ansonsten werde ich aus "den eigenen Werten" nicht schlau. Vielleicht suchst du auch eine Datenstruktur.
Benutzeravatar
Bill987654321
User
Beiträge: 136
Registriert: Sonntag 8. März 2020, 10:56

Jankie hat geschrieben: Montag 6. April 2020, 11:52 In der oberen Schleife überschreibst du nummer_und_mannschaftsname ja immer mit nummer_und_mannschaftsname=[i,mannschaftsname], da wird aber nur der letzte Wert des durchlaufes gespeichert. In der unteren Schleife iterierst du ja durch kopiemanaalphabet, aber gibst nummer_und_mannschaftsname aus.
Können iterierbare Schleifen Datensätze mehrer Mannschaften speichern?
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was sind denn iterierbare Schleifen? Eine Schleife iteriert ueber etwas, sie ist nicht in sich selbst wieder iterierbar. Du kannst natuerlich sowohl Indizes als auch Iteratoren speicher, wenn das dein Begehr ist. Aber ob das zielfuehrend ist, haengt davon ab, was denn eigentlich passieren soll. Vielleicht beschreibst du das mal?

Und auch wenn ander das schon gesagt haben, ich erwaehne das auch noch mal: benutz Funktionen. In Python kann man nicht an beliebige Stellen im Code per GOTO springen.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Bill987654321: Der Datentyp mit Indexzugriffen wie Arrays in BASIC ist in Python die Liste. Allerdings, und ich glaube das hatten wir schon mal, benutzt man in Python nur sehr selten diesen Indexzugriff weil in den allermeisten Fällen eine Indirektion über einen Indexwert unnötig ist.

In ”unstrukturierten” BASIC-Varianten wie der von der Du hier kommst, hat man zudem keine Verbunddatentypen und muss deshalb ”parallele” Datenstrukturen anlegen. Also ein Array mit 18 Manschaftsnamen, ein Array mit 18 Spielanzahlen, ein Array mit 18 Punktanzahlen, und so weiter. Auch das solltest Du in Python gar nicht erst anfangen. Werte die Zusammengehören, speichert man nicht auf mehrere Datenstrukturen verteilt, sondern man fasst alle Werte die sinnvoll zu einer Mannschaft gehören zu einem Objekt zusammen und speichern dann in *einer* Liste 18 Objekte die jeweils die Daten für eine Mannschaft enthalten.

Falls die Werte unveränderbar sein dürfen, bietet sich hier `collections.namedtuple()` an um so einen Typ für eine Mannschaft zu erstellen. Ansonsten wäre das ein Fall für eine eigene Klasse.

Das ist wieder so ein Fall von: Versuche nicht das BASIC-Programm 1:1 zu portieren, sondern schreibe das neu in echtem Python.

Und ich möchte mich auch dem wiederholten Hinweis noch mal anschliessen, dass das da alles nicht auf Modulebene gehört, sondern sinnvoll in Funktionen aufgeteilt.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
Bill987654321
User
Beiträge: 136
Registriert: Sonntag 8. März 2020, 10:56

__blackjack__ hat geschrieben: Montag 6. April 2020, 13:45 @Bill987654321: Der Datentyp mit Indexzugriffen wie Arrays in BASIC ist in Python die Liste. Allerdings, und ich glaube das hatten wir schon mal, benutzt man in Python nur sehr selten diesen Indexzugriff weil in den allermeisten Fällen eine Indirektion über einen Indexwert unnötig ist.

In ”unstrukturierten” BASIC-Varianten wie der von der Du hier kommst, hat man zudem keine Verbunddatentypen und muss deshalb ”parallele” Datenstrukturen anlegen. Also ein Array mit 18 Manschaftsnamen, ein Array mit 18 Spielanzahlen, ein Array mit 18 Punktanzahlen, und so weiter. Auch das solltest Du in Python gar nicht erst anfangen. Werte die Zusammengehören, speichert man nicht auf mehrere Datenstrukturen verteilt, sondern man fasst alle Werte die sinnvoll zu einer Mannschaft gehören zu einem Objekt zusammen und speichern dann in *einer* Liste 18 Objekte die jeweils die Daten für eine Mannschaft enthalten.

Falls die Werte unveränderbar sein dürfen, bietet sich hier `collections.namedtuple()` an um so einen Typ für eine Mannschaft zu erstellen. Ansonsten wäre das ein Fall für eine eigene Klasse.

Das ist wieder so ein Fall von: Versuche nicht das BASIC-Programm 1:1 zu portieren, sondern schreibe das neu in echtem Python.

Und ich möchte mich auch dem wiederholten Hinweis noch mal anschliessen, dass das da alles nicht auf Modulebene gehört, sondern sinnvoll in Funktionen aufgeteilt.
Besonderen Dank für diese Antwort. Ich denke, dass ich alles verstanden habe und werde versuchen, das Geschriebene umzusetzen.
Antworten