Listen vergleichen - Unabhängig von der Reihenfolge des Inhalts

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
Kristally
User
Beiträge: 6
Registriert: Sonntag 12. Februar 2017, 12:15

Hallo allerseits erstmal :)
Ich bin noch ein ziemlicher Anfänger was Python/Programmieren angeht und arbeite mich deswegen gerade durch einen Onlinekurs. Das klappt auch bis jetzt sehr gut und darum ich habe mir eine Aufgabe ausgedacht, um mein derzeitges Wissen einzusetzen/zu kombinieren :P .
Dabei herumgekommen ist ein Programm, was aus einer Textdatei Gästenamen ausliest und "ankommende" Gäste nach ihren Namen fragt. Diese werden dann in eine zweite Liste eingetragen (sofern auf der Gästeliste vorhanden). Wenn alle Gäste anwesend sind, soll das Programm dementsprechend stoppen und "Bescheid sagen" ;).
Das ist nur gerade das Problem. Ich schaffe es gerade nur die Listen miteinander zu vergleichen solange sie auch wirklich identisch sind. Falls sich ein anderer Gast zuerst einträgt und damit von der Reihenfolge nicht exakt mit der Gästeliste übereinstimmt, läuft das Programm für immer weiter und fragt weiter nach "Name?"
Ich hoffe das war verständlich erklärt und ich hoffe auf eine ebenso verständliche Erklärung seitens der Community :lol:
Danke im Vorraus, hier der Code:
Auf der Gästeliste steht: Peter,Hans,Piet

Code: Alles auswählen

#Importieren von Gästeliste
file = open("Eingeladene.txt", "r")
for line in file:
	Gaesteliste = line.split(",")
			
#Leere Liste anlegen/Variablen definieren
Eingetragene = []
nicht_alle_anwesend = True

#Solange nicht alle auf Liste - Schlefe
while nicht_alle_anwesend:
	temp = input("Geben sie ihren Namen ein: ")
	if temp in Gaesteliste:
		Eingetragene.append(temp)
#Checken ob Liste vollständig
		
		if Gaesteliste == Eingetragene:	
			nicht_alle_anwesend = False
			print(Eingetragene)
					
#Wenn Name nicht auf Liste	
	else:
		print("Tut uns leid. Ihr Name steht nicht auf der Gästeliste.")

		
#Ende		
print("Alle Gäste sind anwesend. Schleife unterbrochen!")		

#Stopper
input()	
P.S. Offen für Verbesserungsvorschläge ^^
Benutzeravatar
kbr
User
Beiträge: 1507
Registriert: Mittwoch 15. Oktober 2008, 09:27

Es sind alle da, wenn beide Listen die gleiche Anzahl Einträge haben.
Kristally
User
Beiträge: 6
Registriert: Sonntag 12. Februar 2017, 12:15

kbr hat geschrieben: Sonntag 29. Juli 2018, 17:35 Es sind alle da, wenn beide Listen die gleiche Anzahl Einträge haben.
:cry: :roll: Hab mir ewig den Kopf zerbrochen und über Positionscheck whatever nachgedacht und dabei gehts so einfach :shock: , danke!
Aber nur so aus Interesse: Würde es denn trotzdem ne Methode dafür geben? Listeninhalte in durchgewürfelt miteinander zu vergleichen?
Ansonsten nur danke! ;)
Sirius3
User
Beiträge: 18267
Registriert: Sonntag 21. Oktober 2012, 17:20

@Kristally: Du benutzt nur die letzte Zeile der Datei. Ist das Absicht? Dateien, die man öffnet, sollte man auch wieder schließen. Am besten mit dem with-Statement. Statt der Liste solltest Du ein Set nehmen, da ist die Reihenfolge egal. Variablennamen schreibt man komplett_klein_mit_unterstrich. `temp` ist ein schlechter Variablenname für einen Gast. Statt eines Flags zum Abbruch der while-Schleife schreibt man eine Endlosschleife, die per break beendet wird. Eingerückt wird immer mit 4 Leerzeichen pro Ebene. Das `input` am Ende ist unnötig, da mit der Eingabe ja nichts gemacht wird.

Code: Alles auswählen

with open("Eingeladene.txt") as lines:
    for line in lines:
        # skip to last line
        pass
	gaeste = set(line.split(","))
			
anwesend = set()
while True:
    gast = input("Geben sie ihren Namen ein: ")
	if gast in gaeste:
		anwesend.add(gast)
        if gaeste == anwesend:
            break
	else:
		print("Tut uns leid. Ihr Name steht nicht auf der Gästeliste.")

print("Alle Gäste sind anwesend. Schleife unterbrochen!")		
Kristally
User
Beiträge: 6
Registriert: Sonntag 12. Februar 2017, 12:15

@Sirius3 Hammer, danke!
Das mit der letzen Zeile, nein war keine Absicht, danke :roll: .Und das es sowas wie Sets gibt wusste ich nicht, vielen Dank :)
Benutzeravatar
DeaD_EyE
User
Beiträge: 1232
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Sets sind sehr nützlich. Du musst wissen, dass sets ungeordnet sind und keine doppelten Objekte beinhalten.
Da jeder Gast nur einmal vorkommt, sollte das ja kein Problem sein.

Wenn du mal aus einer Liste doppelte Einträge entfernen willst, dann ist set der einfachste Weg dort hin.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
pixewakb
User
Beiträge: 1413
Registriert: Sonntag 24. April 2011, 19:43

Warum nicht mit einem Wörterbuch arbeiten und die Ankunft darin (z. B. mittels True) vermerken, so kann man sich auch einen Zwischenstand ausgeben lassen. Das alle Eingeladenen auch kommen, wirkt auf mich nicht nach Real Life. So etwas könnte man m. E. dann auch wieder leicht in ein Excel file abkippen, falls es produktiv gebraucht werden würde.
Sirius3
User
Beiträge: 18267
Registriert: Sonntag 21. Oktober 2012, 17:20

@pixewakb: dann fällt halt die Prüfung, ob alle Leute da sind, leicht komplizierter aus.

Code: Alles auswählen

with open("Eingeladene.txt") as lines:
    for line in lines:
        # skip to last line
        pass
    gaeste = dict.fromkeys(line.split(","), False)
			
while True:
    gast = input("Geben sie ihren Namen ein: ")
    try:
        if gaeste[gast]:
            print("Schon da!")
        gaeste[gast] = True
        if all(gaeste.values()):
            break
    except KeyError:
        print("Tut uns leid. Ihr Name steht nicht auf der Gästeliste.")

print("Alle Gäste sind anwesend. Schleife unterbrochen!")
Benutzeravatar
pixewakb
User
Beiträge: 1413
Registriert: Sonntag 24. April 2011, 19:43

Ich will den Thread eigentlich nicht nach vorne holen, aber wahrscheinlich hätte ich das Problem in mehrere (!) Funktionen aufgespalten und mich dabei auch stärker vom ursprünglichen Quellcode entfernt. Ich finde die Lösung wenig praxistauglich (fehlende Praxisnähe) und hätte die Eingabe, wer zur Party gekommen ist, von der Prüfung, ob alle da sind, getrennt. In dem Fall hätte ich die Prüfung wahrscheinlich mit list comprehension zu lösen versucht.
Benutzeravatar
DeaD_EyE
User
Beiträge: 1232
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

pixewakb hat geschrieben: Montag 30. Juli 2018, 15:03 Warum nicht mit einem Wörterbuch arbeiten und die Ankunft darin (z. B. mittels True) vermerken, so kann man sich auch einen Zwischenstand ausgeben lassen.
Ginge auch. Da bräuchte man noch nicht einmal zwei Listen vergleichen.
Du hast ein dict mit allen Gästen, dessen Werte auf False stehen.
Gäste, die sich melden, werden als Key im dict gesucht, wenn vorhanden haben sie eine Einladung.
Dann den Wert des Gastes auf True setzen.

Andere Datenstrukturen zu verwenden, kann ein Programm stark vereinfachen.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Sirius3
User
Beiträge: 18267
Registriert: Sonntag 21. Oktober 2012, 17:20

@DeaD_EyE: wie Du an meinen beiden Beispielimplementierungen siehst, ist der Code für die beiden Datenstrukturvarianten fast gleich, wobei ich zur Prüfung ob alle da sind, ein `gaeste == anwesende` lesbarer finde als ein `all(gaeste.values())` .
Benutzeravatar
DeaD_EyE
User
Beiträge: 1232
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Ja, stimmt :-)
Hatte schon Fälle, bei denen meine Aussage zutrifft. Vorher super kompliziert mit Knoten im Kopf.
Nachdem ich dann einfach mal andere Datenstrukturen verwendet habe, die für den Anwendungszweck passender waren,
wurde der Code auch verständlicher.

An so minimalistischen Beispielen ist das schwer zu erkennen ob jetzt Struktur A oder B besser ist.
Interessant wird es, wenn dann noch weitere Ideen hinzukommen und man den Code erweitert.
sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Antworten