Bestuecken von verschachtelter Liste klappt nicht

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
Jochen1980
User
Beiträge: 40
Registriert: Montag 15. August 2011, 18:44

Servus,

zweiter Post - zweites Anfängerproblem!

Ich will eine Matrix aus einer Liste in einer Liste machen. Jetzt ist die 'matrix' aber viel zu voll. Es sollen 500 Zeilen mit 'Name'\n aus einer Datei gelesen und in eine Datenstruktur überführt werden. Dann soll diese Struktur in eine neue Datei geschrieben werden. Es gibt bestimmt bessere Wege als meinen, aber unabhängig will ich da meinen Fehler verstehen, die Matrix, die ich mit print ausgebe, hat 500 x 500 Einträge. Danke vorab, hier ist der Code:

Code: Alles auswählen

#!/usr/bin/python3

print( "Start ..." )
import sys
import pprint

# Einlesen der Namen
# Name\n
try:
	f = open( "csof500names.txt" )
except:
	print( "Lesen schlug fehl!" )
	sys.exit( 0 )

contentAsString = f.read();
f.close()

#pprint.pprint(contentAsString)

# Datenstruktur in Zielstruktur ueberfuehren, eine Liste aus Listen
# index MsaName
currow = []
matrix = []
curindex = 0
curname = ""

curLineTokens = contentAsString.split(chr(10))
for curLineTok in curLineTokens :
	#ggf. nochmal splitten hier unnoetig
	curname = curLineTok
	currow.append( curindex )
	currow.append( curname )
	matrix.append( currow )
	curindex = curindex + 1
	print( "Zeile: index: ", curindex, "; Name: ", curname, ";" )

print( "Matrix ....\n" )
print( matrix )
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

1.) Verwende doch die Python-Code-tags

2.) Wir kennen die Input-Datenstruktur nicht und auch nicht die Ausgabestruktur - weder die gewünschte noch die, die Du im Moment tatsächlich erhältst.

3.) Da wir keine Dummy-Daten haben, können wir das ganze schlecht selber ausführen. Poste hier stets erst einmal ein minimales und lauffähiges Beispiel.

4.) Solltest Du eine Fehlermeldung erhalten, so poste die hier ebenfalls (copy & paste).

@3.) Du kannst das Öffnen und Parsen doch vernachlässigen und erst einmal eine Dummy-Liste im Code hinterlegen. Alternativ postest Du eine kurze Datendatei mit wenige Einträgen. Damit wäre das Beispiel für uns alle ausführbar und wir könnten sehen, was dabei herauskommt. Im Moment tappe ich im Dunkeln, was 2.) anbelangt.

Was mir am Code so auffiel:

- Code auf Modulebene, dazu noch Code vor den imports!
- Dateien (kannst) solltest Du so öffnen

Code: Alles auswählen

with open(filename, "r") as handler:
    # handler ist hier file object
Dadurch wird die Datei - auch im Fehlerfall - immer geschlossen. ein `.close()` ist also damit obsolet

- Über Textdateien kann man direkt iterieren:

Code: Alles auswählen

with open(filename, "r") as infile:
    for line in infile:
        print line
Das sollte Dir das komische Splitten ersparen.

- Niemals einfach nur `except` ohne konkrete Exception schreiben. Damit fängst Du alle Exceptions ab und das willst Du nicht.

- Wenn man zusätzlich zu einem Listenelement auch einen Index will, so sollte man die Funktion `enumerate` verwenden:

Code: Alles auswählen

for index, line in enumerate(lines):
    print index, lines
Man kann sogar einen Startindex optional als 2. Parameter angeben (wenn man z.B. bei 1 statt bei 0 anfangen will).
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Das passiert, weil du die Liste currow einmal am Anfang initialisierst und dann immer nur Werte anhängst, das heißt sie wird immer länger und länger. Dann hängst du genau diese Liste jedes Mal an Matrix an und da Python nie einfach so Dinge kopiert, verweist jeder Eintrag in matrix auf dieselbe Liste. Und wenn du dann beim nächsten Mal currow verlängerst verlängert sich denmach auch jeder Eintrag in matrix.

Um das zu Umgehen musst du einfach nur currow jdes Mal am Anfang der for-Schleife initialisieren statt nur einmal davor.
Jochen1980
User
Beiträge: 40
Registriert: Montag 15. August 2011, 18:44

Danke euch beiden, einmal für den Hintergrund, den ich wissen wollten und einmal für eine andere wahrscheinlich bessere Lösung!
Antworten