Seite 1 von 1
Joinen (matchen) von Listen ??
Verfasst: Montag 14. Dezember 2009, 12:00
von tejste
Guten Tag,
Vielen Dank für die Tipps die ich (Anfänger) hier finde.
Allerdings habe ich jetzt ein Problem für das ich noch keine Lösung im Forum gefunden habe.
Wäre super wenn mir jemand helfen könnte.
Ich habe eine Textdatei in der Datensätze [r1,z1,78,b1 <Zeilenumbruch> r2,z2,99,b2 <Zeilenumbruch> …..<Zeilenumbruch> r800,z800,987,b800] enthalten sind. Einer dieser Werte und zwar der dritte soll durch einen anderen Wert ersetzt werden. Dieser andere Wert steht in einer anderen Textdatei die so aussieht [bla1,xx1,99,mmmm1 <Zeilenumbruch> bla2,xx2,78,mmmm2…] Die „78“ als Beispiel aus der ersten Datei ist der Schlüssel und dieser soll durch das „mmmm2“ in der 2. Datei ersetzt werden. Der fertige Datensatz soll so ausehen [r1,z1,mmmm2,b1].
Anschliessen soll das ganze Zeug als Datei abgespeichert werden, aber das sollte ich selbst hinbekommen.
Ich jetzt beide Dateien eingelesen, ich habe beide „line“ separiert und gesplittet. Anschliessend versuche ich das joinen. Aber da joint leider nix.
Code: Alles auswählen
g=open(r"c:\results.csv","r")
datei = g.readlines()
g.close()
for splitten in datei:
splitten = line.split(";")
instr=open(r"c:\instruments.csv","r")
instrDatei = instr.readlines()
instr.close()
for lines in instrDatei:
splitinstr = line.split(";")
#joinen
m = splitten[3]
outputdatei=[]
for n in range(1,len(datei)):
for datei[n]in datei:
for k in range(1,len(instrDatei)):
for instrDatei[k] in instrDatei:
if m in splitinstr[3]:
z=datei[n].join(splitinstr[4])
outputdatei.append(z)
[code=]
[/code]
alles läuft durch aber die outputdatei ist leer. Hat irgendeiner eine Idee
Verfasst: Montag 14. Dezember 2009, 12:15
von Defnull
Ein dict wäre hier eine sinnvollere Datenstruktur für die Instrumente.
Code: Alles auswählen
instruments = dict()
with open(r"c:\instruments.csv") as fo:
for line in fo:
parts = line.split(";")
instruments[int(parts[2])] = parts[3]
result = list()
with open(r"c:\results.csv") as fo:
for line in fo:
fields = line.split(";")
fields[2] = instruments.get(int(fields[2]), 'Unknown Instrument')
result.append(fields)
Code wie immer ungetestet. Aber ungeachtet dessen hast du Fehler in Zeile 28 und 30. Die ergeben keinen Sinn.
Re: Joinen (matchen) von Listen ??
Verfasst: Montag 14. Dezember 2009, 12:20
von /me
Diese Schleifen sehen ziemlich wüst aus. Ich habe hier mal einen anderen Ansatz. Zuerst sammele ich in einem Dictionary die Ersetzungsregeln, dann baue ich die Liste mit den Ergebnissen direkt beim Einlesen um.
Code: Alles auswählen
instruments = {}
with open("./instruments.csv") as fi:
for line in fi:
data = line.strip().split(",")
instruments[data[2]] = data[3]
print(instruments)
results = []
with open("./results.csv") as fr:
for line in fr:
data = line.strip().split(",")
results.append([data[0],
data[1],
instruments.get(data[2], data[2]),
data[3]])
print(results)
edit: hmpffff ... 5 Minuten zu spät und dann noch das zu aufwändige append ... dafür allerdings code getestet 
Verfasst: Montag 14. Dezember 2009, 12:26
von jbs
Ich dachte erst du hättest abgeschrieben

Verfasst: Montag 14. Dezember 2009, 12:31
von /me
jbs hat geschrieben:Ich dachte erst du hättest abgeschrieben

Das zeigt zumindest deutlich, dass erfahrene Software-Entwickler (wobei ich das "erfahren" bei mir in Bezug auf Python etwas einschränken möchte) häufig bei der Lösung einer Aufgabe zu ziemlich ähnlichen Ergebnissen kommen.
Anschließend wird man dann von SCO verklagt ...
vielen Dank
Verfasst: Montag 14. Dezember 2009, 12:32
von tejste
das sind minimalistische Ansätze, ich muss wohl noch eine Menge lernen.
das werde ich heute mittag mal ausprobieren und vor allem ich werde mal beide Lösungen testen, auch auf Performance hin. (die Dateien sind ziemlich gross 10.000 und 8000 Datensätze)
Verfasst: Montag 14. Dezember 2009, 12:47
von Defnull
Das kannst du dir sparen: Mes und meine Lösungen haben eine Komplexität von O(n+m). Deine hat O(n*m).
Re: vielen Dank
Verfasst: Montag 14. Dezember 2009, 12:50
von /me
tejste hat geschrieben:das werde ich heute mittag mal ausprobieren und vor allem ich werde mal beide Lösungen testen, auch auf Performance hin. (die Dateien sind ziemlich gross 10.000 und 8000 Datensätze)
"Ziemlich groß" ist was anderes. Ich habe das hier mal mit der 10fachen der von dir angegebenen Menge an Datensätzen ausprobiert. Das Skript braucht auf einem ziemlichen alten Laptop keine Sekunde dafür.
Re: vielen Dank
Verfasst: Montag 14. Dezember 2009, 12:55
von jerch
tejste hat geschrieben:...
(die Dateien sind ziemlich gross 10.000 und 8000 Datensätze)
Ja, groß ist was anderes, weder Speicher noch Laufzeit dürften kritisch werden mit dem Instrumenten-Dictionary (8000) und einer result-Liste von 10000 Einträgen, sofern die Datensätze nicht viel größer sind, als von Dir oben beschrieben. (Zumindest scheinen die Datensätze nicht ganz Deiner Beschreibung zu entsprechen, da Du nach ";" splittest

)
Alternativ könntest Du noch das Einsammeln der result-Einträge sparen und direkt rausschreiben.
Noch ein Wort zum CSV, solange Du garantieren kannst, dass in den csv-Dateien nur simple Feldwerte vorkommen, liefert Deine Vorgehensweise das gewünschte Ergebnis, sollten aber komplexere Feldwerte existieren (z.B. mit Zeilenumbrüchen oder Delimiter im Feldtext) kracht das händische Splitten der Datensätze. Dann doch lieber das [mod]csv[/mod]-Modul benutzen.
Verfasst: Montag 14. Dezember 2009, 13:41
von HWK
@tejste: Der Code, den Du hier gepostet hast, ist bei Dir aber nicht wirklich gelaufen? Wo kommt z.B. line her?
MfG
HWK
Verfasst: Montag 14. Dezember 2009, 14:33
von tejste
ich habe nur das wesentliche gepostet, als Einsteiger lasse ich mir die Zwischenergebnisse immer anzeigen. Das habe ich mich nicht getraut zu posten
Dann sind die Datensätze um einiges länger. Die Result tabelle hat pro Datenzeile 60 Werte die Instrumenten Tabelle knapp 80 Werte.
Verfasst: Montag 14. Dezember 2009, 14:40
von cofi
@OP Du solltest die vielleicht mal
PEP 8 anschaun. (Oder die deutsche Uebersetzung in meiner Signatur.)
Verfasst: Montag 14. Dezember 2009, 15:09
von Defnull
tejste hat geschrieben:Dann sind die Datensätze um einiges länger. Die Result tabelle hat pro Datenzeile 60 Werte die Instrumenten Tabelle knapp 80 Werte.
Gerade dann macht es Sinn, nur die gesuchten Werte zwischen zu speichern und den Rest weg zu werfen.
Verfasst: Montag 14. Dezember 2009, 15:12
von tejste
anyhow... hat funktioniert
ich habe den Code von DEVnull minimal ändern müssen, und das Ergebnis ist genau das was ich haben wollte.
Allerdings muss ich zugeben das mir diese Python Denkweise noch ziemlich unlogisch erscheint.
Vielen Dank
Verfasst: Montag 14. Dezember 2009, 15:14
von Defnull
tejste hat geschrieben:
Allerdings muss ich zugeben das mir diese Python Denkweise noch ziemlich unlogisch erscheint.
Unlogisch? Welcher Schritt erscheint dir denn unlogisch?
Verfasst: Montag 14. Dezember 2009, 15:27
von tejste
ist nicht böse gemeint,
das hier zum Beispiel
fields[2] = instruments.get(fields[2], 'Unknown Instrument')
ich hätte hier eine If Schleife genommen. Dann dieses "get" - kannte ich bisher überhaupt nicht, nur aus dem Java. Beides in Kombination verursacht zumindest bei mir schon Kopfschmerzen

Verfasst: Montag 14. Dezember 2009, 15:29
von Hyperion
tejste hat geschrieben:ist nicht böse gemeint,
das hier zum Beispiel
fields[2] = instruments.get(fields[2], 'Unknown Instrument')
ich hätte hier eine
If Schleife genommen. Dann dieses "get" - kannte ich bisher überhaupt nicht, nur aus dem Java. Beides in Kombination verursacht zumindest bei mir schon Kopfschmerzen

ARGHHHHHHHHH
Was meinst Du mit Kopfschmerzen? Ist doch einfach zu verstehen, oder nicht?
Generell solltest Du evtl. mal das Tutorial durcharbeiten und ab und an in die Dokumentation gucken.